mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-09-03 03:01:13 +12:00
Cleanup
This commit is contained in:
parent
8b5f2bf44e
commit
990bea4f59
117 changed files with 724 additions and 493 deletions
|
@ -15,10 +15,10 @@ import java.nio.file.Path;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a reference to a data source that is managed by X-Pipe.
|
* Represents a reference to a data source that is managed by X-Pipe.
|
||||||
*
|
* <p>
|
||||||
* The actual data is only queried when required and is not cached.
|
* The actual data is only queried when required and is not cached.
|
||||||
* Therefore, the queried data is always up-to-date at the point of calling a method that queries the data.
|
* Therefore, the queried data is always up-to-date at the point of calling a method that queries the data.
|
||||||
*
|
* <p>
|
||||||
* As soon a data source reference is created, the data source is locked
|
* As soon a data source reference is created, the data source is locked
|
||||||
* within X-Pipe to prevent concurrent modification and the problems that can arise from it.
|
* within X-Pipe to prevent concurrent modification and the problems that can arise from it.
|
||||||
* By default, the lock is held until the calling program terminates and prevents
|
* By default, the lock is held until the calling program terminates and prevents
|
||||||
|
@ -29,14 +29,14 @@ public interface DataSource {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NOT YET IMPLEMENTED!
|
* NOT YET IMPLEMENTED!
|
||||||
*
|
* <p>
|
||||||
* Creates a new supplier data source that will be interpreted as the generated data source.
|
* Creates a new supplier data source that will be interpreted as the generated data source.
|
||||||
* In case this program should be a data source generator, this method has to be called at
|
* In case this program should be a data source generator, this method has to be called at
|
||||||
* least once to register that it actually generates a data source.
|
* least once to register that it actually generates a data source.
|
||||||
*
|
* <p>
|
||||||
* All content that is written to this data source until the generator program terminates is
|
* All content that is written to this data source until the generator program terminates is
|
||||||
* will be available later on when the data source is used as a supplier later on.
|
* will be available later on when the data source is used as a supplier later on.
|
||||||
*
|
* <p>
|
||||||
* In case this method is called multiple times, the same data source is returned.
|
* In case this method is called multiple times, the same data source is returned.
|
||||||
*
|
*
|
||||||
* @return the generator data source
|
* @return the generator data source
|
||||||
|
@ -154,6 +154,7 @@ public interface DataSource {
|
||||||
/**
|
/**
|
||||||
* Creates a new data source from an input stream.
|
* Creates a new data source from an input stream.
|
||||||
* 1
|
* 1
|
||||||
|
*
|
||||||
* @param id the data source id
|
* @param id the data source id
|
||||||
* @param type the data source type
|
* @param type the data source type
|
||||||
* @param in the data store to add
|
* @param in the data store to add
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package io.xpipe.api;
|
package io.xpipe.api;
|
||||||
|
|
||||||
import io.xpipe.api.connector.XPipeApiConnection;
|
import io.xpipe.api.connector.XPipeApiConnection;
|
||||||
import io.xpipe.beacon.util.QuietDialogHandler;
|
|
||||||
import io.xpipe.beacon.exchange.cli.StoreAddExchange;
|
import io.xpipe.beacon.exchange.cli.StoreAddExchange;
|
||||||
|
import io.xpipe.beacon.util.QuietDialogHandler;
|
||||||
import io.xpipe.core.store.DataStore;
|
import io.xpipe.core.store.DataStore;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import io.xpipe.core.source.DataSourceId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An accumulator for table data.
|
* An accumulator for table data.
|
||||||
*
|
* <p>
|
||||||
* This class can be used to construct new table data sources by
|
* This class can be used to construct new table data sources by
|
||||||
* accumulating the rows using {@link #add(DataStructureNode)} or {@link #acceptor()} and then calling
|
* accumulating the rows using {@link #add(DataStructureNode)} or {@link #acceptor()} and then calling
|
||||||
* {@link #finish(DataSourceId)} to complete the construction process and create a new data source.
|
* {@link #finish(DataSourceId)} to complete the construction process and create a new data source.
|
||||||
|
|
|
@ -12,7 +12,8 @@ import java.util.Optional;
|
||||||
|
|
||||||
public final class XPipeApiConnection extends BeaconConnection {
|
public final class XPipeApiConnection extends BeaconConnection {
|
||||||
|
|
||||||
private XPipeApiConnection() {}
|
private XPipeApiConnection() {
|
||||||
|
}
|
||||||
|
|
||||||
public static XPipeApiConnection open() {
|
public static XPipeApiConnection open() {
|
||||||
var con = new XPipeApiConnection();
|
var con = new XPipeApiConnection();
|
||||||
|
|
|
@ -12,7 +12,8 @@ public class DataRawImpl extends DataSourceImpl implements DataRaw {
|
||||||
public DataRawImpl(
|
public DataRawImpl(
|
||||||
DataSourceId sourceId,
|
DataSourceId sourceId,
|
||||||
DataSourceConfig sourceConfig,
|
DataSourceConfig sourceConfig,
|
||||||
io.xpipe.core.source.DataSource<?> internalSource) {
|
io.xpipe.core.source.DataSource<?> internalSource
|
||||||
|
) {
|
||||||
super(sourceId, sourceConfig, internalSource);
|
super(sourceId, sourceConfig, internalSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,8 @@ public abstract class DataSourceImpl implements DataSource {
|
||||||
private final io.xpipe.core.source.DataSource<?> internalSource;
|
private final io.xpipe.core.source.DataSource<?> internalSource;
|
||||||
|
|
||||||
public DataSourceImpl(
|
public DataSourceImpl(
|
||||||
DataSourceId sourceId, DataSourceConfig config, io.xpipe.core.source.DataSource<?> internalSource) {
|
DataSourceId sourceId, DataSourceConfig config, io.xpipe.core.source.DataSource<?> internalSource
|
||||||
|
) {
|
||||||
this.sourceId = sourceId;
|
this.sourceId = sourceId;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.internalSource = internalSource;
|
this.internalSource = internalSource;
|
||||||
|
|
|
@ -11,7 +11,8 @@ public class DataStructureImpl extends DataSourceImpl implements DataStructure {
|
||||||
DataStructureImpl(
|
DataStructureImpl(
|
||||||
DataSourceId sourceId,
|
DataSourceId sourceId,
|
||||||
DataSourceConfig sourceConfig,
|
DataSourceConfig sourceConfig,
|
||||||
io.xpipe.core.source.DataSource<?> internalSource) {
|
io.xpipe.core.source.DataSource<?> internalSource
|
||||||
|
) {
|
||||||
super(sourceId, sourceConfig, internalSource);
|
super(sourceId, sourceConfig, internalSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,8 @@ public class DataTableImpl extends DataSourceImpl implements DataTable {
|
||||||
DataTableImpl(
|
DataTableImpl(
|
||||||
DataSourceId id,
|
DataSourceId id,
|
||||||
DataSourceConfig sourceConfig,
|
DataSourceConfig sourceConfig,
|
||||||
io.xpipe.core.source.DataSource<?> internalSource) {
|
io.xpipe.core.source.DataSource<?> internalSource
|
||||||
|
) {
|
||||||
super(id, sourceConfig, internalSource);
|
super(id, sourceConfig, internalSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +74,7 @@ public class DataTableImpl extends DataSourceImpl implements DataTable {
|
||||||
public Iterator<TupleNode> iterator() {
|
public Iterator<TupleNode> iterator() {
|
||||||
return new TableIterator();
|
return new TableIterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
private class TableIterator implements Iterator<TupleNode> {
|
private class TableIterator implements Iterator<TupleNode> {
|
||||||
|
|
|
@ -27,7 +27,8 @@ public class DataTextImpl extends DataSourceImpl implements DataText {
|
||||||
DataTextImpl(
|
DataTextImpl(
|
||||||
DataSourceId sourceId,
|
DataSourceId sourceId,
|
||||||
DataSourceConfig sourceConfig,
|
DataSourceConfig sourceConfig,
|
||||||
io.xpipe.core.source.DataSource<?> internalSource) {
|
io.xpipe.core.source.DataSource<?> internalSource
|
||||||
|
) {
|
||||||
super(sourceId, sourceConfig, internalSource);
|
super(sourceId, sourceConfig, internalSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,9 @@ import io.xpipe.core.data.node.TupleNode;
|
||||||
import io.xpipe.core.data.node.ValueNode;
|
import io.xpipe.core.data.node.ValueNode;
|
||||||
import io.xpipe.core.data.type.TupleType;
|
import io.xpipe.core.data.type.TupleType;
|
||||||
import io.xpipe.core.data.type.ValueType;
|
import io.xpipe.core.data.type.ValueType;
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.OptionalInt;
|
|
||||||
|
|
||||||
public class DataTableAccumulatorTest extends ApiTest {
|
public class DataTableAccumulatorTest extends ApiTest {
|
||||||
|
|
||||||
|
|
|
@ -33,78 +33,8 @@ import static io.xpipe.beacon.BeaconConfig.BODY_SEPARATOR;
|
||||||
|
|
||||||
public class BeaconClient implements AutoCloseable {
|
public class BeaconClient implements AutoCloseable {
|
||||||
|
|
||||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
|
||||||
public abstract static class ClientInformation {
|
|
||||||
|
|
||||||
public final CliClientInformation cli() {
|
|
||||||
return (CliClientInformation) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract String toDisplayString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonTypeName("cli")
|
|
||||||
@Value
|
|
||||||
@Builder
|
|
||||||
@Jacksonized
|
|
||||||
@EqualsAndHashCode(callSuper = false)
|
|
||||||
public static class CliClientInformation extends ClientInformation {
|
|
||||||
|
|
||||||
int consoleWidth;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toDisplayString() {
|
|
||||||
return "X-Pipe CLI";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonTypeName("reachableCheck")
|
|
||||||
@Value
|
|
||||||
@Builder
|
|
||||||
@Jacksonized
|
|
||||||
@EqualsAndHashCode(callSuper = false)
|
|
||||||
public static class ReachableCheckInformation extends ClientInformation {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toDisplayString() {
|
|
||||||
return "Reachable check";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonTypeName("gateway")
|
|
||||||
@Value
|
|
||||||
@Builder
|
|
||||||
@Jacksonized
|
|
||||||
@EqualsAndHashCode(callSuper = false)
|
|
||||||
public static class GatewayClientInformation extends ClientInformation {
|
|
||||||
|
|
||||||
String version;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toDisplayString() {
|
|
||||||
return "X-Pipe Gateway " + version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonTypeName("api")
|
|
||||||
@Value
|
|
||||||
@Builder
|
|
||||||
@Jacksonized
|
|
||||||
@EqualsAndHashCode(callSuper = false)
|
|
||||||
public static class ApiClientInformation extends ClientInformation {
|
|
||||||
|
|
||||||
String version;
|
|
||||||
String language;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toDisplayString() {
|
|
||||||
return String.format("X-Pipe %s API v%s", language, version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final Closeable base;
|
private final Closeable base;
|
||||||
|
|
||||||
private final InputStream in;
|
private final InputStream in;
|
||||||
private final OutputStream out;
|
private final OutputStream out;
|
||||||
|
|
||||||
|
@ -365,4 +295,76 @@ public class BeaconClient implements AutoCloseable {
|
||||||
|
|
||||||
void run() throws E;
|
void run() throws E;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonTypeInfo(
|
||||||
|
use = JsonTypeInfo.Id.NAME,
|
||||||
|
property = "type"
|
||||||
|
)
|
||||||
|
public abstract static class ClientInformation {
|
||||||
|
|
||||||
|
public final CliClientInformation cli() {
|
||||||
|
return (CliClientInformation) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String toDisplayString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonTypeName("cli")
|
||||||
|
@Value
|
||||||
|
@Builder
|
||||||
|
@Jacksonized
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public static class CliClientInformation extends ClientInformation {
|
||||||
|
|
||||||
|
int consoleWidth;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toDisplayString() {
|
||||||
|
return "X-Pipe CLI";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonTypeName("reachableCheck")
|
||||||
|
@Value
|
||||||
|
@Builder
|
||||||
|
@Jacksonized
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public static class ReachableCheckInformation extends ClientInformation {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toDisplayString() {
|
||||||
|
return "Reachable check";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonTypeName("gateway")
|
||||||
|
@Value
|
||||||
|
@Builder
|
||||||
|
@Jacksonized
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public static class GatewayClientInformation extends ClientInformation {
|
||||||
|
|
||||||
|
String version;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toDisplayString() {
|
||||||
|
return "X-Pipe Gateway " + version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonTypeName("api")
|
||||||
|
@Value
|
||||||
|
@Builder
|
||||||
|
@Jacksonized
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public static class ApiClientInformation extends ClientInformation {
|
||||||
|
|
||||||
|
String version;
|
||||||
|
String language;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toDisplayString() {
|
||||||
|
return String.format("X-Pipe %s API v%s", language, version);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,8 @@ public abstract class BeaconConnection implements AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public <REQ extends RequestMessage, RES extends ResponseMessage> void performInputExchange(
|
public <REQ extends RequestMessage, RES extends ResponseMessage> void performInputExchange(
|
||||||
REQ req, BeaconClient.FailableBiConsumer<RES, InputStream, Exception> responseConsumer) {
|
REQ req, BeaconClient.FailableBiConsumer<RES, InputStream, Exception> responseConsumer
|
||||||
|
) {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
|
|
||||||
performInputOutputExchange(req, null, responseConsumer);
|
performInputOutputExchange(req, null, responseConsumer);
|
||||||
|
@ -87,7 +88,8 @@ public abstract class BeaconConnection implements AutoCloseable {
|
||||||
public <REQ extends RequestMessage, RES extends ResponseMessage> void performInputOutputExchange(
|
public <REQ extends RequestMessage, RES extends ResponseMessage> void performInputOutputExchange(
|
||||||
REQ req,
|
REQ req,
|
||||||
BeaconClient.FailableConsumer<OutputStream, IOException> reqWriter,
|
BeaconClient.FailableConsumer<OutputStream, IOException> reqWriter,
|
||||||
BeaconClient.FailableBiConsumer<RES, InputStream, Exception> responseConsumer) {
|
BeaconClient.FailableBiConsumer<RES, InputStream, Exception> responseConsumer
|
||||||
|
) {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -149,7 +151,8 @@ public abstract class BeaconConnection implements AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public <REQ extends RequestMessage, RES extends ResponseMessage> RES performOutputExchange(
|
public <REQ extends RequestMessage, RES extends ResponseMessage> RES performOutputExchange(
|
||||||
REQ req, BeaconClient.FailableConsumer<OutputStream, Exception> reqWriter) {
|
REQ req, BeaconClient.FailableConsumer<OutputStream, Exception> reqWriter
|
||||||
|
) {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -5,7 +5,8 @@ package io.xpipe.beacon;
|
||||||
*/
|
*/
|
||||||
public class BeaconException extends RuntimeException {
|
public class BeaconException extends RuntimeException {
|
||||||
|
|
||||||
public BeaconException() {}
|
public BeaconException() {
|
||||||
|
}
|
||||||
|
|
||||||
public BeaconException(String message) {
|
public BeaconException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
|
|
@ -10,6 +10,7 @@ public class BeaconJacksonModule extends SimpleModule {
|
||||||
context.registerSubtypes(
|
context.registerSubtypes(
|
||||||
new NamedType(BeaconClient.ApiClientInformation.class),
|
new NamedType(BeaconClient.ApiClientInformation.class),
|
||||||
new NamedType(BeaconClient.CliClientInformation.class),
|
new NamedType(BeaconClient.CliClientInformation.class),
|
||||||
new NamedType(BeaconClient.ReachableCheckInformation.class));
|
new NamedType(BeaconClient.ReachableCheckInformation.class)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,9 @@ public class BeaconProxyImpl extends ProxyProvider {
|
||||||
var inputSource = DataSource.createInternalDataSource(source.getType(), new InputStreamStore(inputStream));
|
var inputSource = DataSource.createInternalDataSource(source.getType(), new InputStreamStore(inputStream));
|
||||||
return (T) inputSource.openReadConnection();
|
return (T) inputSource.openReadConnection();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
if (client != null) client.close();
|
if (client != null) {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,7 +127,9 @@ public class BeaconProxyImpl extends ProxyProvider {
|
||||||
var outputSource = DataSource.createInternalDataSource(source.getType(), new OutputStreamStore(outputStream));
|
var outputSource = DataSource.createInternalDataSource(source.getType(), new OutputStreamStore(outputStream));
|
||||||
return (T) outputSource.openWriteConnection(mode);
|
return (T) outputSource.openWriteConnection(mode);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
if (client != null) client.close();
|
if (client != null) {
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,8 @@ public class BeaconServer {
|
||||||
ioe.printStackTrace();
|
ioe.printStackTrace();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"daemon sysout");
|
"daemon sysout"
|
||||||
|
);
|
||||||
out.setDaemon(true);
|
out.setDaemon(true);
|
||||||
out.start();
|
out.start();
|
||||||
|
|
||||||
|
@ -97,7 +98,8 @@ public class BeaconServer {
|
||||||
ioe.printStackTrace();
|
ioe.printStackTrace();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"daemon syserr");
|
"daemon syserr"
|
||||||
|
);
|
||||||
err.setDaemon(true);
|
err.setDaemon(true);
|
||||||
err.start();
|
err.start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,8 @@ package io.xpipe.beacon;
|
||||||
*/
|
*/
|
||||||
public class ClientException extends Exception {
|
public class ClientException extends Exception {
|
||||||
|
|
||||||
public ClientException() {}
|
public ClientException() {
|
||||||
|
}
|
||||||
|
|
||||||
public ClientException(String message) {
|
public ClientException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
|
|
@ -5,7 +5,8 @@ package io.xpipe.beacon;
|
||||||
*/
|
*/
|
||||||
public class ConnectorException extends Exception {
|
public class ConnectorException extends Exception {
|
||||||
|
|
||||||
public ConnectorException() {}
|
public ConnectorException() {
|
||||||
|
}
|
||||||
|
|
||||||
public ConnectorException(String message) {
|
public ConnectorException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
package io.xpipe.beacon;
|
package io.xpipe.beacon;
|
||||||
|
|
||||||
public interface RequestMessage {}
|
public interface RequestMessage {
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
package io.xpipe.beacon;
|
package io.xpipe.beacon;
|
||||||
|
|
||||||
public interface ResponseMessage {}
|
public interface ResponseMessage {
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,8 @@ package io.xpipe.beacon;
|
||||||
*/
|
*/
|
||||||
public class ServerException extends Exception {
|
public class ServerException extends Exception {
|
||||||
|
|
||||||
public ServerException() {}
|
public ServerException() {
|
||||||
|
}
|
||||||
|
|
||||||
public ServerException(String message) {
|
public ServerException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
|
|
@ -31,5 +31,6 @@ public class ForwardExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Response implements ResponseMessage {}
|
public static class Response implements ResponseMessage {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@ package io.xpipe.beacon.exchange;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import io.xpipe.core.util.ProxyFunction;
|
|
||||||
import io.xpipe.beacon.RequestMessage;
|
import io.xpipe.beacon.RequestMessage;
|
||||||
import io.xpipe.beacon.ResponseMessage;
|
import io.xpipe.beacon.ResponseMessage;
|
||||||
|
import io.xpipe.core.util.ProxyFunction;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
@ -21,8 +21,14 @@ public class ProxyFunctionExchange implements MessageExchange {
|
||||||
@Value
|
@Value
|
||||||
public static class Request implements RequestMessage {
|
public static class Request implements RequestMessage {
|
||||||
|
|
||||||
@JsonSerialize(using = ProxyFunction.Serializer.class, as = ProxyFunction.class)
|
@JsonSerialize(
|
||||||
@JsonDeserialize(using = ProxyFunction.Deserializer.class, as = ProxyFunction.class)
|
using = ProxyFunction.Serializer.class,
|
||||||
|
as = ProxyFunction.class
|
||||||
|
)
|
||||||
|
@JsonDeserialize(
|
||||||
|
using = ProxyFunction.Deserializer.class,
|
||||||
|
as = ProxyFunction.class
|
||||||
|
)
|
||||||
ProxyFunction function;
|
ProxyFunction function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +37,14 @@ public class ProxyFunctionExchange implements MessageExchange {
|
||||||
@Value
|
@Value
|
||||||
public static class Response implements ResponseMessage {
|
public static class Response implements ResponseMessage {
|
||||||
|
|
||||||
@JsonSerialize(using = ProxyFunction.Serializer.class, as = ProxyFunction.class)
|
@JsonSerialize(
|
||||||
@JsonDeserialize(using = ProxyFunction.Deserializer.class, as = ProxyFunction.class)
|
using = ProxyFunction.Serializer.class,
|
||||||
|
as = ProxyFunction.class
|
||||||
|
)
|
||||||
|
@JsonDeserialize(
|
||||||
|
using = ProxyFunction.Deserializer.class,
|
||||||
|
as = ProxyFunction.class
|
||||||
|
)
|
||||||
ProxyFunction function;
|
ProxyFunction function;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,8 @@ public class StopExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Request implements RequestMessage {}
|
public static class Request implements RequestMessage {
|
||||||
|
}
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
|
|
|
@ -29,5 +29,6 @@ public class QueryRawDataExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Response implements ResponseMessage {}
|
public static class Response implements ResponseMessage {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,5 +30,6 @@ public class QueryTextDataExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Response implements ResponseMessage {}
|
public static class Response implements ResponseMessage {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,8 @@ public class InstanceExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Request implements RequestMessage {}
|
public static class Request implements RequestMessage {
|
||||||
|
}
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
|
|
|
@ -20,7 +20,8 @@ public class ListCollectionsExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Request implements RequestMessage {}
|
public static class Request implements RequestMessage {
|
||||||
|
}
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
|
|
|
@ -20,7 +20,8 @@ public class ListStoresExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Request implements RequestMessage {}
|
public static class Request implements RequestMessage {
|
||||||
|
}
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
|
|
|
@ -26,5 +26,6 @@ public class ModeExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Response implements ResponseMessage {}
|
public static class Response implements ResponseMessage {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,5 +30,6 @@ public class ReadDrainExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Response implements ResponseMessage {}
|
public static class Response implements ResponseMessage {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,5 +26,6 @@ public class RemoveCollectionExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Response implements ResponseMessage {}
|
public static class Response implements ResponseMessage {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,5 +26,6 @@ public class RemoveStoreExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Response implements ResponseMessage {}
|
public static class Response implements ResponseMessage {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,5 +29,6 @@ public class RenameCollectionExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Response implements ResponseMessage {}
|
public static class Response implements ResponseMessage {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,5 +29,6 @@ public class RenameStoreExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Response implements ResponseMessage {}
|
public static class Response implements ResponseMessage {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,5 +27,6 @@ public class SelectExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Response implements ResponseMessage {}
|
public static class Response implements ResponseMessage {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,8 @@ public class SourceProviderListExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Request implements RequestMessage {}
|
public static class Request implements RequestMessage {
|
||||||
|
}
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
|
|
|
@ -17,7 +17,8 @@ public class StatusExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Request implements RequestMessage {}
|
public static class Request implements RequestMessage {
|
||||||
|
}
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
|
|
|
@ -22,7 +22,8 @@ public class StoreProviderListExchange implements MessageExchange {
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Request implements RequestMessage {}
|
public static class Request implements RequestMessage {
|
||||||
|
}
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
|
|
|
@ -17,7 +17,8 @@ public class VersionExchange implements MessageExchange {
|
||||||
@lombok.extern.jackson.Jacksonized
|
@lombok.extern.jackson.Jacksonized
|
||||||
@lombok.Builder
|
@lombok.Builder
|
||||||
@lombok.Value
|
@lombok.Value
|
||||||
public static class Request implements RequestMessage {}
|
public static class Request implements RequestMessage {
|
||||||
|
}
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
|
|
|
@ -13,15 +13,10 @@ import java.util.UUID;
|
||||||
|
|
||||||
public class QuietDialogHandler {
|
public class QuietDialogHandler {
|
||||||
|
|
||||||
public static void handle(DialogReference ref, BeaconConnection connection) {
|
|
||||||
new QuietDialogHandler(ref, connection, Map.of()).handle();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final UUID dialogKey;
|
private final UUID dialogKey;
|
||||||
private final BeaconConnection connection;
|
private final BeaconConnection connection;
|
||||||
private final Map<String, String> overrides;
|
private final Map<String, String> overrides;
|
||||||
private DialogElement element;
|
private DialogElement element;
|
||||||
|
|
||||||
public QuietDialogHandler(DialogReference ref, BeaconConnection connection, Map<String, String> overrides) {
|
public QuietDialogHandler(DialogReference ref, BeaconConnection connection, Map<String, String> overrides) {
|
||||||
this.dialogKey = ref.getDialogId();
|
this.dialogKey = ref.getDialogId();
|
||||||
this.element = ref.getStart();
|
this.element = ref.getStart();
|
||||||
|
@ -29,6 +24,10 @@ public class QuietDialogHandler {
|
||||||
this.overrides = overrides;
|
this.overrides = overrides;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void handle(DialogReference ref, BeaconConnection connection) {
|
||||||
|
new QuietDialogHandler(ref, connection, Map.of()).handle();
|
||||||
|
}
|
||||||
|
|
||||||
public void handle() {
|
public void handle() {
|
||||||
String response = null;
|
String response = null;
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@ public abstract class Charsetter {
|
||||||
public static Charsetter INSTANCE;
|
public static Charsetter INSTANCE;
|
||||||
private static CharsetterUniverse universe;
|
private static CharsetterUniverse universe;
|
||||||
|
|
||||||
protected Charsetter() {}
|
protected Charsetter() {
|
||||||
|
}
|
||||||
|
|
||||||
protected static void checkInit() {
|
protected static void checkInit() {
|
||||||
if (universe == null) {
|
if (universe == null) {
|
||||||
|
@ -77,7 +78,8 @@ public abstract class Charsetter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Result read(
|
public abstract Result read(
|
||||||
FailableSupplier<InputStream, Exception> in, FailableConsumer<InputStreamReader, Exception> con)
|
FailableSupplier<InputStream, Exception> in, FailableConsumer<InputStreamReader, Exception> con
|
||||||
|
)
|
||||||
throws Exception;
|
throws Exception;
|
||||||
|
|
||||||
public Result detect(StreamDataStore store) throws Exception {
|
public Result detect(StreamDataStore store) throws Exception {
|
||||||
|
|
|
@ -20,8 +20,13 @@ public class StreamCharset {
|
||||||
|
|
||||||
public static final StreamCharset UTF8_BOM = new StreamCharset(
|
public static final StreamCharset UTF8_BOM = new StreamCharset(
|
||||||
StandardCharsets.UTF_8,
|
StandardCharsets.UTF_8,
|
||||||
new byte[] {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF},
|
new byte[]{
|
||||||
Identifiers.get("utf", "8", "bom"));
|
(byte) 0xEF,
|
||||||
|
(byte) 0xBB,
|
||||||
|
(byte) 0xBF
|
||||||
|
},
|
||||||
|
Identifiers.get("utf", "8", "bom")
|
||||||
|
);
|
||||||
|
|
||||||
// ======
|
// ======
|
||||||
// UTF-16
|
// UTF-16
|
||||||
|
@ -32,16 +37,24 @@ public class StreamCharset {
|
||||||
|
|
||||||
public static final StreamCharset UTF16_BE_BOM = new StreamCharset(
|
public static final StreamCharset UTF16_BE_BOM = new StreamCharset(
|
||||||
StandardCharsets.UTF_16BE,
|
StandardCharsets.UTF_16BE,
|
||||||
new byte[] {(byte) 0xFE, (byte) 0xFF},
|
new byte[]{
|
||||||
Identifiers.get("utf", "16", "be", "bom"));
|
(byte) 0xFE,
|
||||||
|
(byte) 0xFF
|
||||||
|
},
|
||||||
|
Identifiers.get("utf", "16", "be", "bom")
|
||||||
|
);
|
||||||
|
|
||||||
public static final StreamCharset UTF16_LE =
|
public static final StreamCharset UTF16_LE =
|
||||||
new StreamCharset(StandardCharsets.UTF_16LE, null, Identifiers.get("utf", "16", "le"));
|
new StreamCharset(StandardCharsets.UTF_16LE, null, Identifiers.get("utf", "16", "le"));
|
||||||
|
|
||||||
public static final StreamCharset UTF16_LE_BOM = new StreamCharset(
|
public static final StreamCharset UTF16_LE_BOM = new StreamCharset(
|
||||||
StandardCharsets.UTF_16LE,
|
StandardCharsets.UTF_16LE,
|
||||||
new byte[] {(byte) 0xFF, (byte) 0xFE},
|
new byte[]{
|
||||||
Identifiers.get("utf", "16", "le", "bom"));
|
(byte) 0xFF,
|
||||||
|
(byte) 0xFE
|
||||||
|
},
|
||||||
|
Identifiers.get("utf", "16", "le", "bom")
|
||||||
|
);
|
||||||
|
|
||||||
public static final StreamCharset UTF16 =
|
public static final StreamCharset UTF16 =
|
||||||
new StreamCharset(StandardCharsets.UTF_16, null, Identifiers.get("utf", "16"));
|
new StreamCharset(StandardCharsets.UTF_16, null, Identifiers.get("utf", "16"));
|
||||||
|
@ -51,30 +64,12 @@ public class StreamCharset {
|
||||||
ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)
|
ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)
|
||||||
? UTF16_BE_BOM.getByteOrderMark()
|
? UTF16_BE_BOM.getByteOrderMark()
|
||||||
: UTF16_LE_BOM.getByteOrderMark(),
|
: UTF16_LE_BOM.getByteOrderMark(),
|
||||||
Identifiers.get("utf", "16", "bom"));
|
Identifiers.get("utf", "16", "bom")
|
||||||
|
);
|
||||||
|
|
||||||
// ======
|
// ======
|
||||||
// UTF-32
|
// 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,
|
||||||
|
@ -83,7 +78,8 @@ public class StreamCharset {
|
||||||
new StreamCharset(
|
new StreamCharset(
|
||||||
StandardCharsets.US_ASCII,
|
StandardCharsets.US_ASCII,
|
||||||
null,
|
null,
|
||||||
Identifiers.join(Identifiers.get("ascii"), Identifiers.get("us", "ascii"))),
|
Identifiers.join(Identifiers.get("ascii"), Identifiers.get("us", "ascii"))
|
||||||
|
),
|
||||||
new StreamCharset(
|
new StreamCharset(
|
||||||
StandardCharsets.ISO_8859_1,
|
StandardCharsets.ISO_8859_1,
|
||||||
null,
|
null,
|
||||||
|
@ -91,16 +87,44 @@ public class StreamCharset {
|
||||||
Identifiers.get("iso", "8859"),
|
Identifiers.get("iso", "8859"),
|
||||||
Identifiers.get("iso", "8859", "1"),
|
Identifiers.get("iso", "8859", "1"),
|
||||||
Identifiers.get("8859"),
|
Identifiers.get("8859"),
|
||||||
Identifiers.get("8859", "1"))),
|
Identifiers.get("8859", "1")
|
||||||
|
)
|
||||||
|
),
|
||||||
new StreamCharset(
|
new StreamCharset(
|
||||||
Charset.forName("Windows-1251"),
|
Charset.forName("Windows-1251"),
|
||||||
null,
|
null,
|
||||||
Identifiers.join(Identifiers.get("windows", "1251"), Identifiers.get("1251"))),
|
Identifiers.join(Identifiers.get("windows", "1251"), Identifiers.get("1251"))
|
||||||
|
),
|
||||||
new StreamCharset(
|
new StreamCharset(
|
||||||
Charset.forName("Windows-1252"),
|
Charset.forName("Windows-1252"),
|
||||||
null,
|
null,
|
||||||
Identifiers.join(Identifiers.get("windows", "1252"), Identifiers.get("1252"))));
|
Identifiers.join(Identifiers.get("windows", "1252"), Identifiers.get("1252"))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
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")
|
||||||
|
);
|
||||||
private static final List<StreamCharset> RARE_NAMED =
|
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);
|
List.of(UTF16_LE, UTF16_LE_BOM, UTF16_BE, UTF16_BE_BOM, UTF32_LE, UTF32_LE_BOM, UTF32_BE, UTF32_BE_BOM);
|
||||||
|
|
||||||
|
@ -119,17 +143,35 @@ public class StreamCharset {
|
||||||
.map(charset -> new StreamCharset(
|
.map(charset -> new StreamCharset(
|
||||||
charset,
|
charset,
|
||||||
null,
|
null,
|
||||||
Identifiers.get(charset.name().split("-")))))
|
Identifiers.get(charset.name().split("-"))
|
||||||
|
))
|
||||||
|
)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
public static final List<StreamCharset> ALL = Stream.concat(COMMON.stream(), RARE.stream()).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;
|
List<String> names;
|
||||||
|
|
||||||
|
public static StreamCharset get(Charset charset, boolean byteOrderMark) {
|
||||||
|
return ALL.stream()
|
||||||
|
.filter(streamCharset ->
|
||||||
|
streamCharset.getCharset().equals(charset) && streamCharset.hasByteOrderMark() == byteOrderMark)
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StreamCharset get(String s) {
|
||||||
|
var found = ALL.stream().filter(streamCharset -> streamCharset.getNames().contains(s.toLowerCase(Locale.ROOT))).findFirst();
|
||||||
|
if (found.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Unknown charset name: " + s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return found.get();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) {
|
if (this == o) {
|
||||||
|
@ -148,23 +190,6 @@ public class StreamCharset {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StreamCharset get(Charset charset, boolean byteOrderMark) {
|
|
||||||
return ALL.stream()
|
|
||||||
.filter(streamCharset ->
|
|
||||||
streamCharset.getCharset().equals(charset) && streamCharset.hasByteOrderMark() == byteOrderMark)
|
|
||||||
.findFirst()
|
|
||||||
.orElseThrow();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static StreamCharset get(String s) {
|
|
||||||
var found = ALL.stream().filter(streamCharset -> streamCharset.getNames().contains(s.toLowerCase(Locale.ROOT))).findFirst();
|
|
||||||
if (found.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("Unknown charset name: " + s);
|
|
||||||
}
|
|
||||||
|
|
||||||
return found.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getNames().get(0);
|
return getNames().get(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,8 @@ public class GenericArrayReader implements GenericAbstractReader {
|
||||||
private GenericAbstractReader currentReader;
|
private GenericAbstractReader currentReader;
|
||||||
private DataStructureNode created;
|
private DataStructureNode created;
|
||||||
|
|
||||||
public GenericArrayReader() {}
|
public GenericArrayReader() {
|
||||||
|
}
|
||||||
|
|
||||||
public static GenericArrayReader newReader(int length) {
|
public static GenericArrayReader newReader(int length) {
|
||||||
var ar = new GenericArrayReader();
|
var ar = new GenericArrayReader();
|
||||||
|
|
|
@ -4,15 +4,21 @@ import java.util.Map;
|
||||||
|
|
||||||
public interface GenericDataStreamCallback {
|
public interface GenericDataStreamCallback {
|
||||||
|
|
||||||
default void onName(String name) {}
|
default void onName(String name) {
|
||||||
|
}
|
||||||
default void onArrayStart(int length) {}
|
|
||||||
|
default void onArrayStart(int length) {
|
||||||
default void onArrayEnd(Map<Integer, String> metaAttributes) {}
|
}
|
||||||
|
|
||||||
default void onTupleStart(int length) {}
|
default void onArrayEnd(Map<Integer, String> metaAttributes) {
|
||||||
|
}
|
||||||
default void onTupleEnd(Map<Integer, String> metaAttributes) {}
|
|
||||||
|
default void onTupleStart(int length) {
|
||||||
default void onValue(byte[] value, Map<Integer, String> metaAttributes) {}
|
}
|
||||||
|
|
||||||
|
default void onTupleEnd(Map<Integer, String> metaAttributes) {
|
||||||
|
}
|
||||||
|
|
||||||
|
default void onValue(byte[] value, Map<Integer, String> metaAttributes) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,8 @@ public class GenericTupleReader implements GenericAbstractReader {
|
||||||
private GenericAbstractReader currentReader;
|
private GenericAbstractReader currentReader;
|
||||||
private DataStructureNode created;
|
private DataStructureNode created;
|
||||||
|
|
||||||
public GenericTupleReader() {}
|
public GenericTupleReader() {
|
||||||
|
}
|
||||||
|
|
||||||
public static GenericTupleReader newReader(int length) {
|
public static GenericTupleReader newReader(int length) {
|
||||||
var tr = new GenericTupleReader();
|
var tr = new GenericTupleReader();
|
||||||
|
|
|
@ -8,7 +8,8 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
public abstract class ArrayNode extends DataStructureNode {
|
public abstract class ArrayNode extends DataStructureNode {
|
||||||
|
|
||||||
protected ArrayNode() {}
|
protected ArrayNode() {
|
||||||
|
}
|
||||||
|
|
||||||
public static ArrayNode empty() {
|
public static ArrayNode empty() {
|
||||||
return of(List.of());
|
return of(List.of());
|
||||||
|
|
|
@ -242,5 +242,6 @@ public abstract class DataStructureNode implements Iterable<DataStructureNode> {
|
||||||
throw unsupported("iterator creation");
|
throw unsupported("iterator creation");
|
||||||
}
|
}
|
||||||
|
|
||||||
public record KeyValue(String key, DataStructureNode value) {}
|
public record KeyValue(String key, DataStructureNode value) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,7 +217,8 @@ public class DataStructureNodePointer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder pointerEvaluation(
|
public Builder pointerEvaluation(
|
||||||
DataStructureNodePointer pointer, Function<DataStructureNode, String> converter) {
|
DataStructureNodePointer pointer, Function<DataStructureNode, String> converter
|
||||||
|
) {
|
||||||
path.add(new FunctionElement((current) -> {
|
path.add(new FunctionElement((current) -> {
|
||||||
var res = pointer.get(current);
|
var res = pointer.get(current);
|
||||||
if (res != null) {
|
if (res != null) {
|
||||||
|
|
|
@ -86,7 +86,8 @@ public class LinkedTupleNode extends TupleNode {
|
||||||
public DataType determineDataType() {
|
public DataType determineDataType() {
|
||||||
return TupleType.of(
|
return TupleType.of(
|
||||||
getKeyNames(),
|
getKeyNames(),
|
||||||
getNodes().stream().map(DataStructureNode::determineDataType).toList());
|
getNodes().stream().map(DataStructureNode::determineDataType).toList()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -67,7 +67,9 @@ public class SimpleTupleNode extends TupleNode {
|
||||||
@Override
|
@Override
|
||||||
public DataStructureNode clear() {
|
public DataStructureNode clear() {
|
||||||
nodes.clear();
|
nodes.clear();
|
||||||
if (names != null) names.clear();
|
if (names != null) {
|
||||||
|
names.clear();
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,8 @@ public abstract class TupleNode extends DataStructureNode {
|
||||||
return hasKeys
|
return hasKeys
|
||||||
? TupleNode.of(
|
? TupleNode.of(
|
||||||
entries.stream().map(KeyValue::key).toList(),
|
entries.stream().map(KeyValue::key).toList(),
|
||||||
entries.stream().map(KeyValue::value).toList())
|
entries.stream().map(KeyValue::value).toList()
|
||||||
|
)
|
||||||
: TupleNode.of(entries.stream().map(KeyValue::value).toList());
|
: TupleNode.of(entries.stream().map(KeyValue::value).toList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@ import java.util.Objects;
|
||||||
|
|
||||||
public abstract class ValueNode extends DataStructureNode {
|
public abstract class ValueNode extends DataStructureNode {
|
||||||
|
|
||||||
protected ValueNode() {}
|
protected ValueNode() {
|
||||||
|
}
|
||||||
|
|
||||||
public static ValueNode nullValue() {
|
public static ValueNode nullValue() {
|
||||||
return new SimpleValueNode(new byte[0]).tag(IS_NULL).asValue();
|
return new SimpleValueNode(new byte[0]).tag(IS_NULL).asValue();
|
||||||
|
|
|
@ -10,7 +10,10 @@ import java.util.Optional;
|
||||||
* To check whether a {@link DataStructureNode} instance conforms to the specified type,
|
* To check whether a {@link DataStructureNode} instance conforms to the specified type,
|
||||||
* the method {@link #matches(DataStructureNode)} can be used.
|
* the method {@link #matches(DataStructureNode)} can be used.
|
||||||
*/
|
*/
|
||||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
@JsonTypeInfo(
|
||||||
|
use = JsonTypeInfo.Id.NAME,
|
||||||
|
property = "type"
|
||||||
|
)
|
||||||
public abstract class DataType {
|
public abstract class DataType {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,11 +2,15 @@ package io.xpipe.core.data.type;
|
||||||
|
|
||||||
public interface DataTypeVisitor {
|
public interface DataTypeVisitor {
|
||||||
|
|
||||||
default void onValue(ValueType type) {}
|
default void onValue(ValueType type) {
|
||||||
|
}
|
||||||
default void onTuple(TupleType type) {}
|
|
||||||
|
default void onTuple(TupleType type) {
|
||||||
default void onArray(ArrayType type) {}
|
}
|
||||||
|
|
||||||
default void onWildcard(WildcardType type) {}
|
default void onArray(ArrayType type) {
|
||||||
|
}
|
||||||
|
|
||||||
|
default void onWildcard(WildcardType type) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,8 @@ public class DataTypeVisitors {
|
||||||
* Creates a visitor that allows for visiting possible recursive columns of table.
|
* Creates a visitor that allows for visiting possible recursive columns of table.
|
||||||
*/
|
*/
|
||||||
public static DataTypeVisitor table(
|
public static DataTypeVisitor table(
|
||||||
Consumer<String> newTuple, Runnable endTuple, BiConsumer<String, DataStructureNodePointer> newValue) {
|
Consumer<String> newTuple, Runnable endTuple, BiConsumer<String, DataStructureNodePointer> newValue
|
||||||
|
) {
|
||||||
return new DataTypeVisitor() {
|
return new DataTypeVisitor() {
|
||||||
private final Stack<TupleType> tuples = new Stack<>();
|
private final Stack<TupleType> tuples = new Stack<>();
|
||||||
private final Stack<Integer> keyIndices = new Stack<>();
|
private final Stack<Integer> keyIndices = new Stack<>();
|
||||||
|
|
|
@ -17,7 +17,8 @@ import java.util.Optional;
|
||||||
@Value
|
@Value
|
||||||
public class WildcardType extends DataType {
|
public class WildcardType extends DataType {
|
||||||
|
|
||||||
private WildcardType() {}
|
private WildcardType() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
|
|
|
@ -7,19 +7,27 @@ import java.util.Map;
|
||||||
|
|
||||||
public interface TypedDataStreamCallback {
|
public interface TypedDataStreamCallback {
|
||||||
|
|
||||||
default void onValue(byte[] data, Map<Integer, String> metaAttributes) {}
|
default void onValue(byte[] data, Map<Integer, String> metaAttributes) {
|
||||||
|
}
|
||||||
default void onGenericNode(DataStructureNode node) {}
|
|
||||||
|
default void onGenericNode(DataStructureNode node) {
|
||||||
default void onTupleBegin(TupleType type) {}
|
}
|
||||||
|
|
||||||
default void onTupleEnd(Map<Integer, String> metaAttributes) {}
|
default void onTupleBegin(TupleType type) {
|
||||||
|
}
|
||||||
default void onArrayBegin(int size) {}
|
|
||||||
|
default void onTupleEnd(Map<Integer, String> metaAttributes) {
|
||||||
default void onArrayEnd(Map<Integer, String> metaAttributes) {}
|
}
|
||||||
|
|
||||||
default void onNodeBegin() {}
|
default void onArrayBegin(int size) {
|
||||||
|
}
|
||||||
default void onNodeEnd() {}
|
|
||||||
|
default void onArrayEnd(Map<Integer, String> metaAttributes) {
|
||||||
|
}
|
||||||
|
|
||||||
|
default void onNodeBegin() {
|
||||||
|
}
|
||||||
|
|
||||||
|
default void onNodeEnd() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ public class TypedDataStructureNodeReader implements TypedAbstractReader {
|
||||||
private int arrayDepth;
|
private int arrayDepth;
|
||||||
private DataType expectedType;
|
private DataType expectedType;
|
||||||
private int currentExpectedTypeIndex;
|
private int currentExpectedTypeIndex;
|
||||||
|
|
||||||
private TypedDataStructureNodeReader(DataType type) {
|
private TypedDataStructureNodeReader(DataType type) {
|
||||||
flattened = new ArrayList<>();
|
flattened = new ArrayList<>();
|
||||||
type.visit(DataTypeVisitors.flatten(flattened::add));
|
type.visit(DataTypeVisitors.flatten(flattened::add));
|
||||||
|
|
|
@ -21,7 +21,8 @@ public class BaseQueryElement extends DialogElement {
|
||||||
|
|
||||||
@JsonCreator
|
@JsonCreator
|
||||||
public BaseQueryElement(
|
public BaseQueryElement(
|
||||||
String description, boolean newLine, boolean required, boolean secret, boolean quiet, String value) {
|
String description, boolean newLine, boolean required, boolean secret, boolean quiet, String value
|
||||||
|
) {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.newLine = newLine;
|
this.newLine = newLine;
|
||||||
this.required = required;
|
this.required = required;
|
||||||
|
|
|
@ -30,13 +30,6 @@ public abstract class Dialog {
|
||||||
protected Object eval;
|
protected Object eval;
|
||||||
private Supplier<?> evaluation;
|
private Supplier<?> evaluation;
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all completion listeners. Intended for internal use only.
|
|
||||||
*/
|
|
||||||
public void clearCompletion() {
|
|
||||||
completion.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an empty dialogue. This dialogue completes immediately and does not handle any questions or answers.
|
* Creates an empty dialogue. This dialogue completes immediately and does not handle any questions or answers.
|
||||||
*/
|
*/
|
||||||
|
@ -65,7 +58,8 @@ public abstract class Dialog {
|
||||||
* @param selected the selected element index
|
* @param selected the selected element index
|
||||||
*/
|
*/
|
||||||
public static Dialog.Choice choice(
|
public static Dialog.Choice choice(
|
||||||
String description, List<io.xpipe.core.dialog.Choice> elements, boolean required, boolean quiet, int selected) {
|
String description, List<io.xpipe.core.dialog.Choice> elements, boolean required, boolean quiet, int selected
|
||||||
|
) {
|
||||||
Dialog.Choice c = new Dialog.Choice(description, elements, required, quiet, selected);
|
Dialog.Choice c = new Dialog.Choice(description, elements, required, quiet, selected);
|
||||||
c.evaluateTo(c::getSelected);
|
c.evaluateTo(c::getSelected);
|
||||||
return c;
|
return c;
|
||||||
|
@ -83,7 +77,8 @@ public abstract class Dialog {
|
||||||
*/
|
*/
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public static <T> Dialog.Choice choice(
|
public static <T> Dialog.Choice choice(
|
||||||
String description, Function<T, String> toString, boolean required, boolean quiet, T def, T... vals) {
|
String description, Function<T, String> toString, boolean required, boolean quiet, T def, T... vals
|
||||||
|
) {
|
||||||
var elements = Arrays.stream(vals)
|
var elements = Arrays.stream(vals)
|
||||||
.map(v -> new io.xpipe.core.dialog.Choice(null, toString.apply(v)))
|
.map(v -> new io.xpipe.core.dialog.Choice(null, toString.apply(v)))
|
||||||
.toList();
|
.toList();
|
||||||
|
@ -120,7 +115,8 @@ public abstract class Dialog {
|
||||||
boolean required,
|
boolean required,
|
||||||
boolean quiet,
|
boolean quiet,
|
||||||
T value,
|
T value,
|
||||||
QueryConverter<T> converter) {
|
QueryConverter<T> converter
|
||||||
|
) {
|
||||||
var q = new <T>Dialog.Query(description, newLine, required, quiet, value, converter, false);
|
var q = new <T>Dialog.Query(description, newLine, required, quiet, value, converter, false);
|
||||||
q.evaluateTo(q::getConvertedValue);
|
q.evaluateTo(q::getConvertedValue);
|
||||||
return q;
|
return q;
|
||||||
|
@ -166,7 +162,8 @@ public abstract class Dialog {
|
||||||
DialogElement currentElement = ds[current].receive(answer);
|
DialogElement currentElement = ds[current].receive(answer);
|
||||||
if (currentElement == null) {
|
if (currentElement == null) {
|
||||||
DialogElement next = null;
|
DialogElement next = null;
|
||||||
while (current < ds.length - 1 && (next = ds[++current].start()) == null) {}
|
while (current < ds.length - 1 && (next = ds[++current].start()) == null) {
|
||||||
|
}
|
||||||
;
|
;
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
@ -357,7 +354,8 @@ public abstract class Dialog {
|
||||||
List<io.xpipe.core.dialog.Choice> elements,
|
List<io.xpipe.core.dialog.Choice> elements,
|
||||||
boolean required,
|
boolean required,
|
||||||
int selected,
|
int selected,
|
||||||
Function<Integer, Dialog> c) {
|
Function<Integer, Dialog> c
|
||||||
|
) {
|
||||||
var choice = new ChoiceElement(description, elements, required, false, selected);
|
var choice = new ChoiceElement(description, elements, required, false, selected);
|
||||||
return new Dialog() {
|
return new Dialog() {
|
||||||
|
|
||||||
|
@ -391,6 +389,13 @@ public abstract class Dialog {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all completion listeners. Intended for internal use only.
|
||||||
|
*/
|
||||||
|
public void clearCompletion() {
|
||||||
|
completion.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: Implement automatic completion mechanism for start as well
|
/* TODO: Implement automatic completion mechanism for start as well
|
||||||
* In case start returns null, the completion is not automatically done.
|
* In case start returns null, the completion is not automatically done.
|
||||||
* */
|
* */
|
||||||
|
@ -497,7 +502,8 @@ public abstract class Dialog {
|
||||||
boolean quiet,
|
boolean quiet,
|
||||||
T value,
|
T value,
|
||||||
QueryConverter<T> converter,
|
QueryConverter<T> converter,
|
||||||
boolean hidden) {
|
boolean hidden
|
||||||
|
) {
|
||||||
this.element = new QueryElement(description, newLine, required, quiet, value, converter, hidden);
|
this.element = new QueryElement(description, newLine, required, quiet, value, converter, hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ package io.xpipe.core.dialog;
|
||||||
*/
|
*/
|
||||||
public class DialogCancelException extends Exception {
|
public class DialogCancelException extends Exception {
|
||||||
|
|
||||||
public DialogCancelException() {}
|
public DialogCancelException() {
|
||||||
|
}
|
||||||
|
|
||||||
public DialogCancelException(String message) {
|
public DialogCancelException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
@ -20,7 +21,8 @@ public class DialogCancelException extends Exception {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DialogCancelException(
|
public DialogCancelException(
|
||||||
String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace
|
||||||
|
) {
|
||||||
super(message, cause, enableSuppression, writableStackTrace);
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,10 @@ import java.util.UUID;
|
||||||
|
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
@ToString
|
@ToString
|
||||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
@JsonTypeInfo(
|
||||||
|
use = JsonTypeInfo.Id.NAME,
|
||||||
|
property = "type"
|
||||||
|
)
|
||||||
public abstract class DialogElement {
|
public abstract class DialogElement {
|
||||||
|
|
||||||
protected String id;
|
protected String id;
|
||||||
|
|
|
@ -14,7 +14,8 @@ public class QueryElement extends BaseQueryElement {
|
||||||
boolean quiet,
|
boolean quiet,
|
||||||
T value,
|
T value,
|
||||||
QueryConverter<T> converter,
|
QueryConverter<T> converter,
|
||||||
boolean hidden) {
|
boolean hidden
|
||||||
|
) {
|
||||||
super(description, newLine, required, hidden, quiet, value != null ? converter.toString(value) : null);
|
super(description, newLine, required, hidden, quiet, value != null ? converter.toString(value) : null);
|
||||||
this.converter = converter;
|
this.converter = converter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,13 +44,13 @@ public class BinarySource extends RawDataSource<StreamDataStore> {
|
||||||
protected RawReadConnection newReadConnection() {
|
protected RawReadConnection newReadConnection() {
|
||||||
return new RawReadConnection() {
|
return new RawReadConnection() {
|
||||||
|
|
||||||
|
private InputStream inputStream;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canRead() throws Exception {
|
public boolean canRead() throws Exception {
|
||||||
return getStore().canOpen();
|
return getStore().canOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
private InputStream inputStream;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() throws Exception {
|
public void init() throws Exception {
|
||||||
if (inputStream != null) {
|
if (inputStream != null) {
|
||||||
|
|
|
@ -32,6 +32,17 @@ public class FileStore extends JacksonizedValue implements FilenameStore, Stream
|
||||||
this.file = file;
|
this.file = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static FileStore local(Path p) {
|
||||||
|
return new FileStore(new LocalStore(), p.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a file store for a file that is local to the callers machine.
|
||||||
|
*/
|
||||||
|
public static FileStore local(String p) {
|
||||||
|
return new FileStore(new LocalStore(), p);
|
||||||
|
}
|
||||||
|
|
||||||
public String getParent() {
|
public String getParent() {
|
||||||
var matcher = Pattern.compile("^(.+?)[^\\\\/]+$").matcher(file);
|
var matcher = Pattern.compile("^(.+?)[^\\\\/]+$").matcher(file);
|
||||||
if (!matcher.matches()) {
|
if (!matcher.matches()) {
|
||||||
|
@ -45,17 +56,6 @@ public class FileStore extends JacksonizedValue implements FilenameStore, Stream
|
||||||
return fileSystem instanceof LocalStore;
|
return fileSystem instanceof LocalStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FileStore local(Path p) {
|
|
||||||
return new FileStore(new LocalStore(), p.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a file store for a file that is local to the callers machine.
|
|
||||||
*/
|
|
||||||
public static FileStore local(String p) {
|
|
||||||
return new FileStore(new LocalStore(), p);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkComplete() throws Exception {
|
public void checkComplete() throws Exception {
|
||||||
if (fileSystem == null) {
|
if (fileSystem == null) {
|
||||||
|
|
|
@ -6,12 +6,12 @@ import java.util.ServiceLoader;
|
||||||
|
|
||||||
public abstract class LocalProcessControlProvider {
|
public abstract class LocalProcessControlProvider {
|
||||||
|
|
||||||
|
private static LocalProcessControlProvider INSTANCE;
|
||||||
|
|
||||||
public static LocalProcessControlProvider get() {
|
public static LocalProcessControlProvider get() {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LocalProcessControlProvider INSTANCE;
|
|
||||||
|
|
||||||
public static void init(ModuleLayer layer) {
|
public static void init(ModuleLayer layer) {
|
||||||
INSTANCE = layer != null
|
INSTANCE = layer != null
|
||||||
? ServiceLoader.load(layer, LocalProcessControlProvider.class)
|
? ServiceLoader.load(layer, LocalProcessControlProvider.class)
|
||||||
|
|
|
@ -45,6 +45,7 @@ public class LocalStore extends JacksonizedValue implements FileSystemStore, Mac
|
||||||
var p = Path.of(file);
|
var p = Path.of(file);
|
||||||
return Files.newOutputStream(p);
|
return Files.newOutputStream(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ShellProcessControl create() {
|
public ShellProcessControl create() {
|
||||||
return LocalProcessControlProvider.create();
|
return LocalProcessControlProvider.create();
|
||||||
|
|
|
@ -12,6 +12,7 @@ public class PreservingTableWriteConnection extends PreservingWriteConnection im
|
||||||
public PreservingTableWriteConnection(DataSource<?> source, DataSourceConnection connection, boolean append) {
|
public PreservingTableWriteConnection(DataSource<?> source, DataSourceConnection connection, boolean append) {
|
||||||
super(DataSourceType.TABLE, source, append, connection);
|
super(DataSourceType.TABLE, source, append, connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<TableMapping> createMapping(TupleType inputType) throws Exception {
|
public Optional<TableMapping> createMapping(TupleType inputType) throws Exception {
|
||||||
return ((TableWriteConnection) connection).createMapping(inputType);
|
return ((TableWriteConnection) connection).createMapping(inputType);
|
||||||
|
|
|
@ -15,7 +15,8 @@ public class PreservingWriteConnection implements DataSourceConnection {
|
||||||
private final boolean append;
|
private final boolean append;
|
||||||
|
|
||||||
public PreservingWriteConnection(
|
public PreservingWriteConnection(
|
||||||
DataSourceType type, DataSource<?> source, boolean append, DataSourceConnection connection) {
|
DataSourceType type, DataSource<?> source, boolean append, DataSourceConnection connection
|
||||||
|
) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.append = append;
|
this.append = append;
|
||||||
|
|
|
@ -21,14 +21,6 @@ import java.nio.channels.Pipe;
|
||||||
@Getter
|
@Getter
|
||||||
public class SinkDrainStore extends JacksonizedValue implements KnownFormatStreamDataStore, StatefulDataStore {
|
public class SinkDrainStore extends JacksonizedValue implements KnownFormatStreamDataStore, StatefulDataStore {
|
||||||
|
|
||||||
public static enum State {
|
|
||||||
NONE_CONNECTED,
|
|
||||||
PRODUCER_CONNECTED,
|
|
||||||
CONSUMER_CONNECTED,
|
|
||||||
OPEN,
|
|
||||||
CLOSED
|
|
||||||
}
|
|
||||||
|
|
||||||
private final StreamCharset charset;
|
private final StreamCharset charset;
|
||||||
private final NewLine newLine;
|
private final NewLine newLine;
|
||||||
|
|
||||||
|
@ -163,4 +155,12 @@ public class SinkDrainStore extends JacksonizedValue implements KnownFormatStrea
|
||||||
throw new IllegalStateException("Consumer is already connected");
|
throw new IllegalStateException("Consumer is already connected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static enum State {
|
||||||
|
NONE_CONNECTED,
|
||||||
|
PRODUCER_CONNECTED,
|
||||||
|
CONSUMER_CONNECTED,
|
||||||
|
OPEN,
|
||||||
|
CLOSED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,8 @@ public class StdinDataStore extends JacksonizedValue implements StreamDataStore
|
||||||
// Prevent closing the standard in when the returned input stream is closed
|
// Prevent closing the standard in when the returned input stream is closed
|
||||||
return new FilterInputStream(in) {
|
return new FilterInputStream(in) {
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {}
|
public void close() throws IOException {
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,8 @@ public class StdoutDataStore extends JacksonizedValue implements StreamDataStore
|
||||||
// Create an output stream that will write to standard out but will not close it
|
// Create an output stream that will write to standard out but will not close it
|
||||||
return new FilterOutputStream(System.out) {
|
return new FilterOutputStream(System.out) {
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {}
|
public void close() throws IOException {
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ public class XpbtReadConnection extends StreamReadConnection implements TableRea
|
||||||
private TupleType dataType;
|
private TupleType dataType;
|
||||||
private TypedDataStreamParser parser;
|
private TypedDataStreamParser parser;
|
||||||
private boolean empty;
|
private boolean empty;
|
||||||
|
|
||||||
protected XpbtReadConnection(XpbtSource source) {
|
protected XpbtReadConnection(XpbtSource source) {
|
||||||
super(source.getStore(), null);
|
super(source.getStore(), null);
|
||||||
this.store = source.getStore();
|
this.store = source.getStore();
|
||||||
|
@ -46,7 +47,8 @@ public class XpbtReadConnection extends StreamReadConnection implements TableRea
|
||||||
this.inputStream.skip(headerLength + 1);
|
this.inputStream.skip(headerLength + 1);
|
||||||
List<String> names = JacksonMapper.newMapper()
|
List<String> names = JacksonMapper.newMapper()
|
||||||
.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE)
|
.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE)
|
||||||
.readerFor(new TypeReference<List<String>>() {})
|
.readerFor(new TypeReference<List<String>>() {
|
||||||
|
})
|
||||||
.readValue(header);
|
.readValue(header);
|
||||||
TupleType dataType = TupleType.tableType(names);
|
TupleType dataType = TupleType.tableType(names);
|
||||||
this.dataType = dataType;
|
this.dataType = dataType;
|
||||||
|
|
|
@ -9,16 +9,6 @@ public interface OsType {
|
||||||
Linux LINUX = new Linux();
|
Linux LINUX = new Linux();
|
||||||
Mac MAC = new Mac();
|
Mac MAC = new Mac();
|
||||||
|
|
||||||
String getName();
|
|
||||||
|
|
||||||
String getTempDirectory(ShellProcessControl pc) throws Exception;
|
|
||||||
|
|
||||||
String normalizeFileName(String file);
|
|
||||||
|
|
||||||
Map<String, String> getProperties(ShellProcessControl pc) throws Exception;
|
|
||||||
|
|
||||||
String determineOperatingSystemName(ShellProcessControl pc) throws Exception;
|
|
||||||
|
|
||||||
public static OsType getLocal() {
|
public static OsType getLocal() {
|
||||||
String osName = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
|
String osName = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
|
||||||
if ((osName.contains("mac")) || (osName.contains("darwin"))) {
|
if ((osName.contains("mac")) || (osName.contains("darwin"))) {
|
||||||
|
@ -32,6 +22,16 @@ public interface OsType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
String getTempDirectory(ShellProcessControl pc) throws Exception;
|
||||||
|
|
||||||
|
String normalizeFileName(String file);
|
||||||
|
|
||||||
|
Map<String, String> getProperties(ShellProcessControl pc) throws Exception;
|
||||||
|
|
||||||
|
String determineOperatingSystemName(ShellProcessControl pc) throws Exception;
|
||||||
|
|
||||||
static class Windows implements OsType {
|
static class Windows implements OsType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -24,6 +24,7 @@ public interface ProcessControl extends Closeable, AutoCloseable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void close() throws IOException;
|
void close() throws IOException;
|
||||||
|
|
||||||
void kill() throws Exception;
|
void kill() throws Exception;
|
||||||
|
|
||||||
ProcessControl start() throws Exception;
|
ProcessControl start() throws Exception;
|
||||||
|
|
|
@ -18,7 +18,8 @@ public class ProcessOutputException extends Exception {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ProcessOutputException(
|
protected ProcessOutputException(
|
||||||
String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace
|
||||||
|
) {
|
||||||
super(message, cause, enableSuppression, writableStackTrace);
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,8 @@ public interface ShellProcessControl extends ProcessControl {
|
||||||
|
|
||||||
ShellProcessControl subShell(
|
ShellProcessControl subShell(
|
||||||
@NonNull Function<ShellProcessControl, String> command,
|
@NonNull Function<ShellProcessControl, String> command,
|
||||||
BiFunction<ShellProcessControl, String, String> terminalCommand);
|
BiFunction<ShellProcessControl, String, String> terminalCommand
|
||||||
|
);
|
||||||
|
|
||||||
void executeCommand(String command) throws Exception;
|
void executeCommand(String command) throws Exception;
|
||||||
|
|
||||||
|
@ -81,7 +82,8 @@ public interface ShellProcessControl extends ProcessControl {
|
||||||
CommandProcessControl command(Function<ShellProcessControl, String> command);
|
CommandProcessControl command(Function<ShellProcessControl, String> command);
|
||||||
|
|
||||||
CommandProcessControl command(
|
CommandProcessControl command(
|
||||||
Function<ShellProcessControl, String> command, Function<ShellProcessControl, String> terminalCommand);
|
Function<ShellProcessControl, String> command, Function<ShellProcessControl, String> terminalCommand
|
||||||
|
);
|
||||||
|
|
||||||
default CommandProcessControl command(String command) {
|
default CommandProcessControl command(String command) {
|
||||||
return command(shellProcessControl -> command);
|
return command(shellProcessControl -> command);
|
||||||
|
|
|
@ -7,7 +7,10 @@ import java.nio.charset.Charset;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
@JsonTypeInfo(
|
||||||
|
use = JsonTypeInfo.Id.NAME,
|
||||||
|
property = "type"
|
||||||
|
)
|
||||||
public interface ShellType {
|
public interface ShellType {
|
||||||
|
|
||||||
String getScriptFileEnding();
|
String getScriptFileEnding();
|
||||||
|
|
|
@ -32,7 +32,13 @@ public class ShellTypes {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ShellType[] getAllShellTypes() {
|
public static ShellType[] getAllShellTypes() {
|
||||||
return new ShellType[] {CMD, POWERSHELL, ZSH, BASH, SH};
|
return new ShellType[]{
|
||||||
|
CMD,
|
||||||
|
POWERSHELL,
|
||||||
|
ZSH,
|
||||||
|
BASH,
|
||||||
|
SH
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonTypeName("cmd")
|
@JsonTypeName("cmd")
|
||||||
|
@ -295,7 +301,8 @@ public class ShellTypes {
|
||||||
@Override
|
@Override
|
||||||
public void elevate(ShellProcessControl control, String command, String displayCommand) throws Exception {
|
public void elevate(ShellProcessControl control, String command, String displayCommand) throws Exception {
|
||||||
try (CommandProcessControl c = control.command(
|
try (CommandProcessControl c = control.command(
|
||||||
"([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)")
|
"([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security" +
|
||||||
|
".Principal.WindowsBuiltinRole]::Administrator)")
|
||||||
.start()) {
|
.start()) {
|
||||||
if (c.startAndCheckExit()) {
|
if (c.startAndCheckExit()) {
|
||||||
throw new IllegalStateException("The command \"" + displayCommand + "\" requires elevation.");
|
throw new IllegalStateException("The command \"" + displayCommand + "\" requires elevation.");
|
||||||
|
|
|
@ -23,7 +23,10 @@ import java.util.Optional;
|
||||||
* This instance is only valid in combination with its associated data store instance.
|
* This instance is only valid in combination with its associated data store instance.
|
||||||
*/
|
*/
|
||||||
@SuperBuilder
|
@SuperBuilder
|
||||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
@JsonTypeInfo(
|
||||||
|
use = JsonTypeInfo.Id.NAME,
|
||||||
|
property = "type"
|
||||||
|
)
|
||||||
public abstract class DataSource<DS extends DataStore> extends JacksonizedValue {
|
public abstract class DataSource<DS extends DataStore> extends JacksonizedValue {
|
||||||
|
|
||||||
protected DS store;
|
protected DS store;
|
||||||
|
|
|
@ -9,7 +9,9 @@ public interface DataSourceConnection extends AutoCloseable {
|
||||||
* Initializes this connection. Required to be called
|
* Initializes this connection. Required to be called
|
||||||
* exactly once prior to attempting to use this connection.
|
* exactly once prior to attempting to use this connection.
|
||||||
*/
|
*/
|
||||||
default void init() throws Exception {}
|
default void init() throws Exception {
|
||||||
|
}
|
||||||
default void close() throws Exception {}
|
|
||||||
|
default void close() throws Exception {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import lombok.Getter;
|
||||||
* To allow for a simple usage of data source ids, the collection and entry names are trimmed and
|
* To allow for a simple usage of data source ids, the collection and entry names are trimmed and
|
||||||
* converted to lower case names when creating them.
|
* converted to lower case names when creating them.
|
||||||
* The two names are separated by a colon and are therefore not allowed to contain colons themselves.
|
* The two names are separated by a colon and are therefore not allowed to contain colons themselves.
|
||||||
*
|
* <p>
|
||||||
* A missing collection name indicates that the data source exists only temporarily.
|
* A missing collection name indicates that the data source exists only temporarily.
|
||||||
*
|
*
|
||||||
* @see #create(String, String)
|
* @see #create(String, String)
|
||||||
|
|
|
@ -10,7 +10,7 @@ import java.util.Objects;
|
||||||
* Represents a reference to an X-Pipe data source.
|
* Represents a reference to an X-Pipe data source.
|
||||||
* Using {@link DataSourceReference} instances instead of {@link DataSourceId}
|
* Using {@link DataSourceReference} instances instead of {@link DataSourceId}
|
||||||
* instances is mainly done for user convenience purposes.
|
* instances is mainly done for user convenience purposes.
|
||||||
*
|
* <p>
|
||||||
* While a {@link DataSourceId} represents a unique and canonical identifier for an X-Pipe data source,
|
* While a {@link DataSourceId} represents a unique and canonical identifier for an X-Pipe data source,
|
||||||
* there also exist easier and shorter ways to address a data source.
|
* there also exist easier and shorter ways to address a data source.
|
||||||
* This convenience comes at the price of ambiguity and instability for other types of references.
|
* This convenience comes at the price of ambiguity and instability for other types of references.
|
||||||
|
@ -105,8 +105,12 @@ public interface DataSourceReference {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) {
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Id id = (Id) o;
|
Id id = (Id) o;
|
||||||
return value.equals(id.value);
|
return value.equals(id.value);
|
||||||
}
|
}
|
||||||
|
@ -155,8 +159,12 @@ public interface DataSourceReference {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) {
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Name n = (Name) o;
|
Name n = (Name) o;
|
||||||
return value.equals(n.value);
|
return value.equals(n.value);
|
||||||
}
|
}
|
||||||
|
@ -201,7 +209,9 @@ public interface DataSourceReference {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return o != null && getClass() == o.getClass();
|
return o != null && getClass() == o.getClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,28 +45,6 @@ public abstract class TableDataSource<DS extends DataStore> extends DataSource<D
|
||||||
return newReadConnection();
|
return newReadConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NoArgsConstructor
|
|
||||||
private static class CreateMappingFunction extends SimpleProxyFunction<TableMapping> {
|
|
||||||
|
|
||||||
private TableDataSource<?> source;
|
|
||||||
private TupleType type;
|
|
||||||
|
|
||||||
public CreateMappingFunction(TableDataSource<?> source, TupleType type) {
|
|
||||||
this.source = source;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TableMapping mapping;
|
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
public void callLocal() {
|
|
||||||
try (TableWriteConnection w = source.openWriteConnection(WriteMode.REPLACE)) {
|
|
||||||
w.init();
|
|
||||||
mapping = w.createMapping(type).orElse(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final Optional<TableMapping> createMapping(TupleType inputType) throws Exception {
|
public final Optional<TableMapping> createMapping(TupleType inputType) throws Exception {
|
||||||
return Optional.ofNullable(new CreateMappingFunction(this, inputType).callAndGet());
|
return Optional.ofNullable(new CreateMappingFunction(this, inputType).callAndGet());
|
||||||
}
|
}
|
||||||
|
@ -100,4 +78,25 @@ public abstract class TableDataSource<DS extends DataStore> extends DataSource<D
|
||||||
protected TableReadConnection newReadConnection() {
|
protected TableReadConnection newReadConnection() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
private static class CreateMappingFunction extends SimpleProxyFunction<TableMapping> {
|
||||||
|
|
||||||
|
private TableDataSource<?> source;
|
||||||
|
private TupleType type;
|
||||||
|
private TableMapping mapping;
|
||||||
|
|
||||||
|
public CreateMappingFunction(TableDataSource<?> source, TupleType type) {
|
||||||
|
this.source = source;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public void callLocal() {
|
||||||
|
try (TableWriteConnection w = source.openWriteConnection(WriteMode.REPLACE)) {
|
||||||
|
w.init();
|
||||||
|
mapping = w.createMapping(type).orElse(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,17 @@ import java.util.stream.IntStream;
|
||||||
@Getter
|
@Getter
|
||||||
public class TableMapping {
|
public class TableMapping {
|
||||||
|
|
||||||
|
protected final Integer[] columMap;
|
||||||
|
private final TupleType inputType;
|
||||||
|
private final TupleType outputType;
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public TableMapping(TupleType inputType, TupleType outputType, Integer[] columMap) {
|
||||||
|
this.inputType = inputType;
|
||||||
|
this.outputType = outputType;
|
||||||
|
this.columMap = columMap;
|
||||||
|
}
|
||||||
|
|
||||||
private static Integer[] range(int size) {
|
private static Integer[] range(int size) {
|
||||||
var array = new Integer[size];
|
var array = new Integer[size];
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
|
@ -58,19 +69,6 @@ public class TableMapping {
|
||||||
return OptionalInt.empty();
|
return OptionalInt.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final TupleType inputType;
|
|
||||||
|
|
||||||
private final TupleType outputType;
|
|
||||||
|
|
||||||
protected final Integer[] columMap;
|
|
||||||
|
|
||||||
@JsonCreator
|
|
||||||
public TableMapping(TupleType inputType, TupleType outputType, Integer[] columMap) {
|
|
||||||
this.inputType = inputType;
|
|
||||||
this.outputType = outputType;
|
|
||||||
this.columMap = columMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isIdentity() {
|
public boolean isIdentity() {
|
||||||
return inputType.equals(outputType)
|
return inputType.equals(outputType)
|
||||||
&& Arrays.equals(columMap, range(getInputType().getSize()));
|
&& Arrays.equals(columMap, range(getInputType().getSize()));
|
||||||
|
|
|
@ -9,6 +9,9 @@ import java.util.ServiceLoader;
|
||||||
|
|
||||||
public class WriteMode extends JacksonizedValue {
|
public class WriteMode extends JacksonizedValue {
|
||||||
|
|
||||||
|
public static final Replace REPLACE = new Replace();
|
||||||
|
public static final Append APPEND = new Append();
|
||||||
|
public static final Prepend PREPEND = new Prepend();
|
||||||
private static final List<WriteMode> ALL = new ArrayList<>();
|
private static final List<WriteMode> ALL = new ArrayList<>();
|
||||||
|
|
||||||
public static void init(ModuleLayer layer) {
|
public static void init(ModuleLayer layer) {
|
||||||
|
@ -19,27 +22,26 @@ public class WriteMode extends JacksonizedValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonTypeName("replace")
|
|
||||||
public static final class Replace extends WriteMode {}
|
|
||||||
|
|
||||||
@JsonTypeName("append")
|
|
||||||
public static final class Append extends WriteMode {}
|
|
||||||
|
|
||||||
@JsonTypeName("prepend")
|
|
||||||
public static final class Prepend extends WriteMode {}
|
|
||||||
|
|
||||||
public static final Replace REPLACE = new Replace();
|
|
||||||
public static final Append APPEND = new Append();
|
|
||||||
public static final Prepend PREPEND = new Prepend();
|
|
||||||
|
|
||||||
public final String getId() {
|
|
||||||
return getClass().getAnnotation(JsonTypeName.class).value();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static WriteMode byId(String id) {
|
public static WriteMode byId(String id) {
|
||||||
return ALL.stream()
|
return ALL.stream()
|
||||||
.filter(writeMode -> writeMode.getId().equalsIgnoreCase(id))
|
.filter(writeMode -> writeMode.getId().equalsIgnoreCase(id))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElseThrow();
|
.orElseThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final String getId() {
|
||||||
|
return getClass().getAnnotation(JsonTypeName.class).value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonTypeName("replace")
|
||||||
|
public static final class Replace extends WriteMode {
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonTypeName("append")
|
||||||
|
public static final class Append extends WriteMode {
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonTypeName("prepend")
|
||||||
|
public static final class Prepend extends WriteMode {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,10 @@ import java.util.Optional;
|
||||||
*
|
*
|
||||||
* @see DataSource
|
* @see DataSource
|
||||||
*/
|
*/
|
||||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
@JsonTypeInfo(
|
||||||
|
use = JsonTypeInfo.Id.NAME,
|
||||||
|
property = "type"
|
||||||
|
)
|
||||||
public interface DataStore {
|
public interface DataStore {
|
||||||
|
|
||||||
default boolean shouldPersist() {
|
default boolean shouldPersist() {
|
||||||
|
@ -61,23 +64,25 @@ public interface DataStore {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs a validation of this data store.
|
* Performs a validation of this data store.
|
||||||
*
|
* <p>
|
||||||
* This validation can include one of multiple things:
|
* This validation can include one of multiple things:
|
||||||
* - Sanity checks of individual properties
|
* - Sanity checks of individual properties
|
||||||
* - Existence checks
|
* - Existence checks
|
||||||
* - Connection checks
|
* - Connection checks
|
||||||
*
|
* <p>
|
||||||
* All in all, a successful execution of this method should almost guarantee
|
* All in all, a successful execution of this method should almost guarantee
|
||||||
* that the data store can be successfully accessed in the near future.
|
* that the data store can be successfully accessed in the near future.
|
||||||
*
|
* <p>
|
||||||
* Note that some checks may take a long time, for example if a connection has to be validated.
|
* Note that some checks may take a long time, for example if a connection has to be validated.
|
||||||
* The caller should therefore expect a runtime of multiple seconds when calling this method.
|
* The caller should therefore expect a runtime of multiple seconds when calling this method.
|
||||||
*
|
*
|
||||||
* @throws Exception if any part of the validation went wrong
|
* @throws Exception if any part of the validation went wrong
|
||||||
*/
|
*/
|
||||||
default void validate() throws Exception {}
|
default void validate() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
default void checkComplete() throws Exception {}
|
default void checkComplete() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
default boolean delete() throws Exception {
|
default boolean delete() throws Exception {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -28,9 +28,11 @@ public interface ShellStore extends DataStore {
|
||||||
return pc.getShellType();
|
return pc.getShellType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void validate() throws Exception {
|
default void validate() throws Exception {
|
||||||
try (ShellProcessControl pc = create().start()) {}
|
try (ShellProcessControl pc = create().start()) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public default String queryMachineName() throws Exception {
|
public default String queryMachineName() throws Exception {
|
||||||
|
|
|
@ -9,6 +9,7 @@ public interface StatefulDataStore extends DataStore {
|
||||||
default <T> T getState(String key, Class<T> c, T def) {
|
default <T> T getState(String key, Class<T> c, T def) {
|
||||||
return DataStateProvider.get().getState(this, key, c, () -> def);
|
return DataStateProvider.get().getState(this, key, c, () -> def);
|
||||||
}
|
}
|
||||||
|
|
||||||
default <T> T getOrComputeState(String key, Class<T> c, Supplier<T> def) {
|
default <T> T getOrComputeState(String key, Class<T> c, Supplier<T> def) {
|
||||||
return DataStateProvider.get().getState(this, key, c, def);
|
return DataStateProvider.get().getState(this, key, c, def);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,8 @@ public class CoreJacksonModule extends SimpleModule {
|
||||||
new NamedType(BaseQueryElement.class),
|
new NamedType(BaseQueryElement.class),
|
||||||
new NamedType(ChoiceElement.class),
|
new NamedType(ChoiceElement.class),
|
||||||
new NamedType(BusyElement.class),
|
new NamedType(BusyElement.class),
|
||||||
new NamedType(HeaderElement.class));
|
new NamedType(HeaderElement.class)
|
||||||
|
);
|
||||||
|
|
||||||
addSerializer(Charset.class, new CharsetSerializer());
|
addSerializer(Charset.class, new CharsetSerializer());
|
||||||
addDeserializer(Charset.class, new CharsetDeserializer());
|
addDeserializer(Charset.class, new CharsetDeserializer());
|
||||||
|
@ -197,12 +198,16 @@ public class CoreJacksonModule extends SimpleModule {
|
||||||
@JsonSerialize(as = Throwable.class)
|
@JsonSerialize(as = Throwable.class)
|
||||||
public abstract static class ThrowableTypeMixIn {
|
public abstract static class ThrowableTypeMixIn {
|
||||||
|
|
||||||
@JsonIdentityInfo(generator = ObjectIdGenerators.StringIdGenerator.class, property = "$id")
|
@JsonIdentityInfo(
|
||||||
|
generator = ObjectIdGenerators.StringIdGenerator.class,
|
||||||
|
property = "$id"
|
||||||
|
)
|
||||||
private Throwable cause;
|
private Throwable cause;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonSerialize(as = DataSourceReference.class)
|
@JsonSerialize(as = DataSourceReference.class)
|
||||||
public abstract static class DataSourceReferenceTypeMixIn {}
|
public abstract static class DataSourceReferenceTypeMixIn {
|
||||||
|
}
|
||||||
|
|
||||||
public class NullSerializer extends JsonSerializer<Object> {
|
public class NullSerializer extends JsonSerializer<Object> {
|
||||||
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
|
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
|
||||||
|
|
|
@ -42,7 +42,9 @@ public class Deobfuscator {
|
||||||
deobfuscate(throwable.getCause());
|
deobfuscate(throwable.getCause());
|
||||||
}
|
}
|
||||||
for (Throwable suppressed : throwable.getSuppressed()) {
|
for (Throwable suppressed : throwable.getSuppressed()) {
|
||||||
if (suppressed != throwable) deobfuscate(suppressed);
|
if (suppressed != throwable) {
|
||||||
|
deobfuscate(suppressed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
System.err.println("Deobfuscation failed");
|
System.err.println("Deobfuscation failed");
|
||||||
|
@ -67,7 +69,8 @@ public class Deobfuscator {
|
||||||
var proc = new ProcessBuilder(
|
var proc = new ProcessBuilder(
|
||||||
"retrace." + (OsType.getLocal().equals(OsType.WINDOWS) ? "bat" : "sh"),
|
"retrace." + (OsType.getLocal().equals(OsType.WINDOWS) ? "bat" : "sh"),
|
||||||
System.getenv("XPIPE_MAPPING"),
|
System.getenv("XPIPE_MAPPING"),
|
||||||
file.toString())
|
file.toString()
|
||||||
|
)
|
||||||
.redirectErrorStream(true);
|
.redirectErrorStream(true);
|
||||||
var active = proc.start();
|
var active = proc.start();
|
||||||
var out = new String(active.getInputStream().readAllBytes()).replaceAll("\r\n", NewLine.LF.getNewLineString());
|
var out = new String(active.getInputStream().readAllBytes()).replaceAll("\r\n", NewLine.LF.getNewLineString());
|
||||||
|
|
|
@ -20,6 +20,7 @@ public class Identifiers {
|
||||||
String.join("", split),
|
String.join("", split),
|
||||||
String.join(" ", split),
|
String.join(" ", split),
|
||||||
String.join("_", split),
|
String.join("_", split),
|
||||||
String.join("-", split));
|
String.join("-", split)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,14 @@ import lombok.SneakyThrows;
|
||||||
import lombok.experimental.SuperBuilder;
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
@SuperBuilder
|
@SuperBuilder
|
||||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
@JsonTypeInfo(
|
||||||
|
use = JsonTypeInfo.Id.NAME,
|
||||||
|
property = "type"
|
||||||
|
)
|
||||||
public class JacksonizedValue {
|
public class JacksonizedValue {
|
||||||
|
|
||||||
public JacksonizedValue() {}
|
public JacksonizedValue() {
|
||||||
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public final String toString() {
|
public final String toString() {
|
||||||
|
|
|
@ -24,6 +24,26 @@ public abstract class ProxyFunction {
|
||||||
layer = l;
|
layer = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public ProxyFunction callAndCopy() {
|
||||||
|
var proxyStore = ProxyProvider.get().getProxy(getProxyBase());
|
||||||
|
if (proxyStore != null) {
|
||||||
|
return ProxyProvider.get().call(this, proxyStore);
|
||||||
|
} else {
|
||||||
|
callLocal();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
protected Object getProxyBase() {
|
||||||
|
var first = Arrays.stream(getClass().getDeclaredFields()).findFirst().orElseThrow();
|
||||||
|
first.setAccessible(true);
|
||||||
|
return first.get(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void callLocal();
|
||||||
|
|
||||||
public static class Serializer extends StdSerializer<ProxyFunction> {
|
public static class Serializer extends StdSerializer<ProxyFunction> {
|
||||||
|
|
||||||
protected Serializer() {
|
protected Serializer() {
|
||||||
|
@ -60,24 +80,4 @@ public abstract class ProxyFunction {
|
||||||
return (ProxyFunction) JacksonMapper.getDefault().treeToValue(tree, targetClass);
|
return (ProxyFunction) JacksonMapper.getDefault().treeToValue(tree, targetClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
public ProxyFunction callAndCopy() {
|
|
||||||
var proxyStore = ProxyProvider.get().getProxy(getProxyBase());
|
|
||||||
if (proxyStore != null) {
|
|
||||||
return ProxyProvider.get().call(this, proxyStore);
|
|
||||||
} else {
|
|
||||||
callLocal();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
protected Object getProxyBase() {
|
|
||||||
var first = Arrays.stream(getClass().getDeclaredFields()).findFirst().orElseThrow();
|
|
||||||
first.setAccessible(true);
|
|
||||||
return first.get(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void callLocal();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,10 +29,12 @@ public abstract class ProxyProvider {
|
||||||
public abstract boolean isRemote(Object base);
|
public abstract boolean isRemote(Object base);
|
||||||
|
|
||||||
public abstract <T extends DataSourceReadConnection> T createRemoteReadConnection(
|
public abstract <T extends DataSourceReadConnection> T createRemoteReadConnection(
|
||||||
DataSource<?> source, ShellStore proxy) throws Exception;
|
DataSource<?> source, ShellStore proxy
|
||||||
|
) throws Exception;
|
||||||
|
|
||||||
public abstract <T extends DataSourceConnection> T createRemoteWriteConnection(
|
public abstract <T extends DataSourceConnection> T createRemoteWriteConnection(
|
||||||
DataSource<?> source, WriteMode mode, ShellStore proxy) throws Exception;
|
DataSource<?> source, WriteMode mode, ShellStore proxy
|
||||||
|
) throws Exception;
|
||||||
|
|
||||||
public abstract ProxyFunction call(ProxyFunction func, ShellStore proxy);
|
public abstract ProxyFunction call(ProxyFunction func, ShellStore proxy);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,18 @@ public class DataSourceIdTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@ValueSource(strings = {"abc", "abc:", "ab::c", "::abc", " ab", "::::", "", " "})
|
@ValueSource(
|
||||||
|
strings = {
|
||||||
|
"abc",
|
||||||
|
"abc:",
|
||||||
|
"ab::c",
|
||||||
|
"::abc",
|
||||||
|
" ab",
|
||||||
|
"::::",
|
||||||
|
"",
|
||||||
|
" "
|
||||||
|
}
|
||||||
|
)
|
||||||
public void testFromStringInvalidParameters(String arg) {
|
public void testFromStringInvalidParameters(String arg) {
|
||||||
Assertions.assertThrows(IllegalArgumentException.class, () -> {
|
Assertions.assertThrows(IllegalArgumentException.class, () -> {
|
||||||
DataSourceId.fromString(arg);
|
DataSourceId.fromString(arg);
|
||||||
|
|
|
@ -22,7 +22,13 @@ public class DataSourceReferenceTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@ValueSource(strings = {"abc:", "ab::c", "::abc"})
|
@ValueSource(
|
||||||
|
strings = {
|
||||||
|
"abc:",
|
||||||
|
"ab::c",
|
||||||
|
"::abc"
|
||||||
|
}
|
||||||
|
)
|
||||||
public void parseInvalidParameters(String arg) {
|
public void parseInvalidParameters(String arg) {
|
||||||
Assertions.assertThrows(IllegalArgumentException.class, () -> {
|
Assertions.assertThrows(IllegalArgumentException.class, () -> {
|
||||||
DataSourceReference.parse(arg);
|
DataSourceReference.parse(arg);
|
||||||
|
|
|
@ -34,7 +34,8 @@ public abstract class Comp<S extends CompStructure<?>> {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <IR extends Region, SIN extends CompStructure<IR>, OR extends Region> Comp<CompStructure<OR>> derive(
|
public static <IR extends Region, SIN extends CompStructure<IR>, OR extends Region> Comp<CompStructure<OR>> derive(
|
||||||
Comp<SIN> comp, Function<IR, OR> r) {
|
Comp<SIN> comp, Function<IR, OR> r
|
||||||
|
) {
|
||||||
return of(() -> r.apply((IR) comp.createRegion()));
|
return of(() -> r.apply((IR) comp.createRegion()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ public class GrowAugment<S extends CompStructure<?>> implements Augment<S> {
|
||||||
|
|
||||||
private final boolean width;
|
private final boolean width;
|
||||||
private final boolean height;
|
private final boolean height;
|
||||||
|
|
||||||
private GrowAugment(boolean width, boolean height) {
|
private GrowAugment(boolean width, boolean height) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
|
@ -30,7 +31,8 @@ public class GrowAugment<S extends CompStructure<?>> implements Augment<S> {
|
||||||
- p.getInsets().getLeft()
|
- p.getInsets().getLeft()
|
||||||
- p.getInsets().getRight(),
|
- p.getInsets().getRight(),
|
||||||
p.widthProperty(),
|
p.widthProperty(),
|
||||||
p.insetsProperty()));
|
p.insetsProperty()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
if (height) {
|
if (height) {
|
||||||
r.prefHeightProperty()
|
r.prefHeightProperty()
|
||||||
|
@ -45,7 +47,8 @@ public class GrowAugment<S extends CompStructure<?>> implements Augment<S> {
|
||||||
return val;
|
return val;
|
||||||
},
|
},
|
||||||
p.heightProperty(),
|
p.heightProperty(),
|
||||||
p.insetsProperty()));
|
p.insetsProperty()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,8 +56,12 @@ public class GrowAugment<S extends CompStructure<?>> implements Augment<S> {
|
||||||
public void augment(S struc) {
|
public void augment(S struc) {
|
||||||
struc.get().parentProperty().addListener((c, o, n) -> {
|
struc.get().parentProperty().addListener((c, o, n) -> {
|
||||||
if (o instanceof Region) {
|
if (o instanceof Region) {
|
||||||
if (width) struc.get().prefWidthProperty().unbind();
|
if (width) {
|
||||||
if (height) struc.get().prefHeightProperty().unbind();
|
struc.get().prefWidthProperty().unbind();
|
||||||
|
}
|
||||||
|
if (height) {
|
||||||
|
struc.get().prefHeightProperty().unbind();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bind(struc.get(), n);
|
bind(struc.get(), n);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue