mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 17:10:27 +00:00
Refactor exchanges, add dialog APIs, add store providers
This commit is contained in:
parent
f4f9c1d978
commit
696568d5bc
50 changed files with 791 additions and 206 deletions
|
@ -13,7 +13,7 @@ import lombok.extern.jackson.Jacksonized;
|
||||||
/**
|
/**
|
||||||
* Performs an edit for a data source.
|
* Performs an edit for a data source.
|
||||||
*/
|
*/
|
||||||
public class EditExecuteExchange implements MessageExchange<EditExecuteExchange.Request, EditExecuteExchange.Response> {
|
public class EditExecuteExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
|
|
@ -12,23 +12,13 @@ import lombok.extern.jackson.Jacksonized;
|
||||||
/**
|
/**
|
||||||
* Requests to edit a data source.
|
* Requests to edit a data source.
|
||||||
*/
|
*/
|
||||||
public class EditPreparationExchange implements MessageExchange<EditPreparationExchange.Request, EditPreparationExchange.Response> {
|
public class EditPreparationExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "editPreparation";
|
return "editPreparation";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<EditPreparationExchange.Request> getRequestClass() {
|
|
||||||
return EditPreparationExchange.Request.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<EditPreparationExchange.Response> getResponseClass() {
|
|
||||||
return EditPreparationExchange.Response.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package io.xpipe.beacon.exchange;
|
package io.xpipe.beacon.exchange;
|
||||||
|
|
||||||
import io.xpipe.beacon.message.RequestMessage;
|
|
||||||
import io.xpipe.beacon.message.ResponseMessage;
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A message exchange scheme that implements a certain functionality.
|
* A message exchange scheme that implements a certain functionality.
|
||||||
*/
|
*/
|
||||||
public interface MessageExchange<RQ extends RequestMessage, RP extends ResponseMessage> {
|
public interface MessageExchange {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The unique id of this exchange that will be included in the messages.
|
* The unique id of this exchange that will be included in the messages.
|
||||||
|
@ -19,10 +17,10 @@ public interface MessageExchange<RQ extends RequestMessage, RP extends ResponseM
|
||||||
*/
|
*/
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
default Class<RQ> getRequestClass() {
|
default Class<?> getRequestClass() {
|
||||||
var c = getClass().getSuperclass();
|
var c = getClass().getSuperclass();
|
||||||
var name = (MessageExchange.class.isAssignableFrom(c) ? c : getClass()).getName() + "$Request";
|
var name = (MessageExchange.class.isAssignableFrom(c) ? c : getClass()).getName() + "$Request";
|
||||||
return (Class<RQ>) Class.forName(name);
|
return Class.forName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,9 +28,9 @@ public interface MessageExchange<RQ extends RequestMessage, RP extends ResponseM
|
||||||
*/
|
*/
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
default Class<RP> getResponseClass() {
|
default Class<?> getResponseClass() {
|
||||||
var c = getClass().getSuperclass();
|
var c = getClass().getSuperclass();
|
||||||
var name = (MessageExchange.class.isAssignableFrom(c) ? c : getClass()).getName() + "$Response";
|
var name = (MessageExchange.class.isAssignableFrom(c) ? c : getClass()).getName() + "$Response";
|
||||||
return (Class<RP>) Class.forName(name);
|
return Class.forName(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,37 +10,34 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class MessageExchanges {
|
public class MessageExchanges {
|
||||||
|
|
||||||
private static Set<MessageExchange<?,?>> ALL;
|
private static Set<MessageExchange> ALL;
|
||||||
|
|
||||||
private static void loadAll() {
|
private static void loadAll() {
|
||||||
if (ALL == null) {
|
if (ALL == null) {
|
||||||
ALL = ServiceLoader.load(MessageExchange.class).stream()
|
ALL = ServiceLoader.load(MessageExchange.class).stream()
|
||||||
.map(s -> (MessageExchange<?,?>) s.get()).collect(Collectors.toSet());
|
.map(s -> (MessageExchange) s.get()).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
public static <RQ extends RequestMessage, RP extends ResponseMessage> Optional<MessageExchange> byId(String name) {
|
||||||
public static <RQ extends RequestMessage, RP extends ResponseMessage> Optional<MessageExchange<RQ, RP>> byId(String name) {
|
|
||||||
loadAll();
|
loadAll();
|
||||||
var r = ALL.stream().filter(d -> d.getId().equals(name)).findAny();
|
var r = ALL.stream().filter(d -> d.getId().equals(name)).findAny();
|
||||||
return Optional.ofNullable((MessageExchange<RQ, RP>) r.orElse(null));
|
return Optional.ofNullable((MessageExchange) r.orElse(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
public static <RQ extends RequestMessage, RP extends ResponseMessage> Optional<MessageExchange> byRequest(RQ req) {
|
||||||
public static <RQ extends RequestMessage, RP extends ResponseMessage> Optional<MessageExchange<RQ, RP>> byRequest(RQ req) {
|
|
||||||
loadAll();
|
loadAll();
|
||||||
var r = ALL.stream().filter(d -> d.getRequestClass().equals(req.getClass())).findAny();
|
var r = ALL.stream().filter(d -> d.getRequestClass().equals(req.getClass())).findAny();
|
||||||
return Optional.ofNullable((MessageExchange<RQ, RP>) r.orElse(null));
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
public static <RQ extends RequestMessage, RP extends ResponseMessage> Optional<MessageExchange> byResponse(RP rep) {
|
||||||
public static <RQ extends RequestMessage, RP extends ResponseMessage> Optional<MessageExchange<RQ, RP>> byResponse(RP rep) {
|
|
||||||
loadAll();
|
loadAll();
|
||||||
var r = ALL.stream().filter(d -> d.getResponseClass().equals(rep.getClass())).findAny();
|
var r = ALL.stream().filter(d -> d.getResponseClass().equals(rep.getClass())).findAny();
|
||||||
return Optional.ofNullable((MessageExchange<RQ, RP>) r.orElse(null));
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<MessageExchange<?,?>> getAll() {
|
public static Set<MessageExchange> getAll() {
|
||||||
loadAll();
|
loadAll();
|
||||||
return ALL;
|
return ALL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,23 +12,13 @@ import lombok.extern.jackson.Jacksonized;
|
||||||
/**
|
/**
|
||||||
* Queries general information about a data source.
|
* Queries general information about a data source.
|
||||||
*/
|
*/
|
||||||
public class QueryDataSourceExchange implements MessageExchange<QueryDataSourceExchange.Request, QueryDataSourceExchange.Response> {
|
public class QueryDataSourceExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "queryDataSource";
|
return "queryDataSource";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<QueryDataSourceExchange.Request> getRequestClass() {
|
|
||||||
return QueryDataSourceExchange.Request.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<QueryDataSourceExchange.Response> getResponseClass() {
|
|
||||||
return QueryDataSourceExchange.Response.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
|
|
|
@ -13,23 +13,13 @@ import lombok.extern.jackson.Jacksonized;
|
||||||
/**
|
/**
|
||||||
* Sends stream-based data to a daemon.
|
* Sends stream-based data to a daemon.
|
||||||
*/
|
*/
|
||||||
public class ReadExecuteExchange implements MessageExchange<ReadExecuteExchange.Request, ReadExecuteExchange.Response> {
|
public class ReadExecuteExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "readExecute";
|
return "readExecute";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<ReadExecuteExchange.Request> getRequestClass() {
|
|
||||||
return ReadExecuteExchange.Request.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<ReadExecuteExchange.Response> getResponseClass() {
|
|
||||||
return ReadExecuteExchange.Response.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
|
|
|
@ -3,7 +3,7 @@ package io.xpipe.beacon.exchange;
|
||||||
import io.xpipe.beacon.message.RequestMessage;
|
import io.xpipe.beacon.message.RequestMessage;
|
||||||
import io.xpipe.beacon.message.ResponseMessage;
|
import io.xpipe.beacon.message.ResponseMessage;
|
||||||
import io.xpipe.core.source.DataSourceConfigInstance;
|
import io.xpipe.core.source.DataSourceConfigInstance;
|
||||||
import io.xpipe.core.store.StreamDataStore;
|
import io.xpipe.core.store.DataStore;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
|
@ -12,23 +12,13 @@ import lombok.extern.jackson.Jacksonized;
|
||||||
/**
|
/**
|
||||||
* Prepares a client to send stream-based data to a daemon.
|
* Prepares a client to send stream-based data to a daemon.
|
||||||
*/
|
*/
|
||||||
public class ReadPreparationExchange implements MessageExchange<ReadPreparationExchange.Request, ReadPreparationExchange.Response> {
|
public class ReadPreparationExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "readPreparation";
|
return "readPreparation";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<ReadPreparationExchange.Request> getRequestClass() {
|
|
||||||
return ReadPreparationExchange.Request.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<ReadPreparationExchange.Response> getResponseClass() {
|
|
||||||
return ReadPreparationExchange.Response.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
|
@ -36,7 +26,7 @@ public class ReadPreparationExchange implements MessageExchange<ReadPreparationE
|
||||||
String provider;
|
String provider;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
StreamDataStore store;
|
DataStore store;
|
||||||
|
|
||||||
boolean configureAll;
|
boolean configureAll;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import lombok.NonNull;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
public class RemoveCollectionExchange implements MessageExchange<RemoveCollectionExchange.Request, RemoveCollectionExchange.Response> {
|
public class RemoveCollectionExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import lombok.NonNull;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
public class RemoveEntryExchange implements MessageExchange<RemoveEntryExchange.Request, RemoveEntryExchange.Response> {
|
public class RemoveEntryExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import lombok.NonNull;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
public class RenameCollectionExchange implements MessageExchange<RenameCollectionExchange.Request, RenameCollectionExchange.Response> {
|
public class RenameCollectionExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import lombok.NonNull;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
public class RenameEntryExchange implements MessageExchange<RenameEntryExchange.Request, RenameEntryExchange.Response> {
|
public class RenameEntryExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
|
|
@ -9,23 +9,13 @@ import lombok.extern.jackson.Jacksonized;
|
||||||
/**
|
/**
|
||||||
* Requests the daemon to stop.
|
* Requests the daemon to stop.
|
||||||
*/
|
*/
|
||||||
public class StopExchange implements MessageExchange<StopExchange.Request, StopExchange.Response> {
|
public class StopExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "stop";
|
return "stop";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<StopExchange.Request> getRequestClass() {
|
|
||||||
return StopExchange.Request.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<StopExchange.Response> getResponseClass() {
|
|
||||||
return StopExchange.Response.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
|
|
|
@ -10,23 +10,13 @@ import lombok.extern.jackson.Jacksonized;
|
||||||
/**
|
/**
|
||||||
* Stores a stream of data in a storage.
|
* Stores a stream of data in a storage.
|
||||||
*/
|
*/
|
||||||
public class StoreStreamExchange implements MessageExchange<StoreStreamExchange.Request, StoreStreamExchange.Response> {
|
public class StoreStreamExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "storeStream";
|
return "storeStream";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<StoreStreamExchange.Request> getRequestClass() {
|
|
||||||
return StoreStreamExchange.Request.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<StoreStreamExchange.Response> getResponseClass() {
|
|
||||||
return StoreStreamExchange.Response.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
|
|
|
@ -9,7 +9,7 @@ import lombok.NonNull;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
public class QueryRawDataExchange implements MessageExchange<QueryRawDataExchange.Request, QueryRawDataExchange.Response> {
|
public class QueryRawDataExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
|
|
@ -12,23 +12,13 @@ import lombok.extern.jackson.Jacksonized;
|
||||||
/**
|
/**
|
||||||
* Queries data of a table data source in the xpbt format.
|
* Queries data of a table data source in the xpbt format.
|
||||||
*/
|
*/
|
||||||
public class QueryTableDataExchange implements MessageExchange<QueryTableDataExchange.Request, QueryTableDataExchange.Response> {
|
public class QueryTableDataExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "queryTableData";
|
return "queryTableData";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<QueryTableDataExchange.Request> getRequestClass() {
|
|
||||||
return QueryTableDataExchange.Request.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<QueryTableDataExchange.Response> getResponseClass() {
|
|
||||||
return QueryTableDataExchange.Response.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
|
|
|
@ -9,7 +9,7 @@ import lombok.NonNull;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
public class QueryTextDataExchange implements MessageExchange<QueryTextDataExchange.Request, QueryTextDataExchange.Response> {
|
public class QueryTextDataExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import lombok.NonNull;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
public class ConvertExchange implements MessageExchange<ConvertExchange.Request, ConvertExchange.Response> {
|
public class ConvertExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
|
|
@ -3,12 +3,14 @@ package io.xpipe.beacon.exchange.cli;
|
||||||
import io.xpipe.beacon.exchange.MessageExchange;
|
import io.xpipe.beacon.exchange.MessageExchange;
|
||||||
import io.xpipe.beacon.message.RequestMessage;
|
import io.xpipe.beacon.message.RequestMessage;
|
||||||
import io.xpipe.beacon.message.ResponseMessage;
|
import io.xpipe.beacon.message.ResponseMessage;
|
||||||
import io.xpipe.core.source.DataSourceConfigInstance;
|
import io.xpipe.core.config.DialogElement;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
public class DialogExchange implements MessageExchange<DialogExchange.Request, DialogExchange.Response> {
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class DialogExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
@ -29,8 +31,7 @@ public class DialogExchange implements MessageExchange<DialogExchange.Request, D
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Request implements RequestMessage {
|
public static class Request implements RequestMessage {
|
||||||
DataSourceConfigInstance instance;
|
UUID dialogKey;
|
||||||
String key;
|
|
||||||
String value;
|
String value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ public class DialogExchange implements MessageExchange<DialogExchange.Request, D
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
public static class Response implements ResponseMessage {
|
public static class Response implements ResponseMessage {
|
||||||
|
DialogElement element;
|
||||||
String errorMsg;
|
String errorMsg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,23 +10,13 @@ import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ListCollectionsExchange implements MessageExchange<ListCollectionsExchange.Request, ListCollectionsExchange.Response> {
|
public class ListCollectionsExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "listCollections";
|
return "listCollections";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<Request> getRequestClass() {
|
|
||||||
return Request.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<Response> getResponseClass() {
|
|
||||||
return Response.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
|
|
|
@ -10,23 +10,13 @@ import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ListEntriesExchange implements MessageExchange<ListEntriesExchange.Request, ListEntriesExchange.Response> {
|
public class ListEntriesExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "listEntries";
|
return "listEntries";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<Request> getRequestClass() {
|
|
||||||
return Request.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<Response> getResponseClass() {
|
|
||||||
return Response.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
|
|
|
@ -8,23 +8,13 @@ import lombok.NonNull;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
public class ModeExchange implements MessageExchange<ModeExchange.Request, ModeExchange.Response> {
|
public class ModeExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "mode";
|
return "mode";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<ModeExchange.Request> getRequestClass() {
|
|
||||||
return ModeExchange.Request.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<ModeExchange.Response> getResponseClass() {
|
|
||||||
return ModeExchange.Response.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
|
|
|
@ -13,7 +13,7 @@ import lombok.extern.jackson.Jacksonized;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class ProviderListExchange implements MessageExchange<ProviderListExchange.Request, ProviderListExchange.Response> {
|
public class ProviderListExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
|
|
@ -9,23 +9,13 @@ import lombok.NonNull;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
public class SelectExchange implements MessageExchange<SelectExchange.Request, SelectExchange.Response> {
|
public class SelectExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "select";
|
return "select";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<SelectExchange.Request> getRequestClass() {
|
|
||||||
return SelectExchange.Request.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<SelectExchange.Response> getResponseClass() {
|
|
||||||
return SelectExchange.Response.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
|
|
|
@ -7,23 +7,13 @@ import lombok.Builder;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
public class StatusExchange implements MessageExchange<StatusExchange.Request, StatusExchange.Response> {
|
public class StatusExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "status";
|
return "status";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<Request> getRequestClass() {
|
|
||||||
return Request.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<Response> getResponseClass() {
|
|
||||||
return Response.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
@Value
|
@Value
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package io.xpipe.beacon.exchange.cli;
|
||||||
|
|
||||||
|
import io.xpipe.beacon.exchange.MessageExchange;
|
||||||
|
import io.xpipe.beacon.message.RequestMessage;
|
||||||
|
import io.xpipe.beacon.message.ResponseMessage;
|
||||||
|
import io.xpipe.core.config.DialogElement;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.Value;
|
||||||
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class StoreAddExchange implements MessageExchange {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return "storeAdd";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Jacksonized
|
||||||
|
@Builder
|
||||||
|
@Value
|
||||||
|
public static class Request implements RequestMessage {
|
||||||
|
@NonNull
|
||||||
|
String input;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Jacksonized
|
||||||
|
@Builder
|
||||||
|
@Value
|
||||||
|
public static class Response implements ResponseMessage {
|
||||||
|
UUID dialogKey;
|
||||||
|
DialogElement dialogElement;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,23 +7,13 @@ import lombok.Builder;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
public class VersionExchange implements MessageExchange<VersionExchange.Request, VersionExchange.Response> {
|
public class VersionExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "version";
|
return "version";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<VersionExchange.Request> getRequestClass() {
|
|
||||||
return VersionExchange.Request.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<VersionExchange.Response> getResponseClass() {
|
|
||||||
return VersionExchange.Response.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@lombok.extern.jackson.Jacksonized
|
@lombok.extern.jackson.Jacksonized
|
||||||
@lombok.Builder
|
@lombok.Builder
|
||||||
@lombok.Value
|
@lombok.Value
|
||||||
|
|
|
@ -13,7 +13,7 @@ import lombok.extern.jackson.Jacksonized;
|
||||||
/**
|
/**
|
||||||
* Output the data source contents.
|
* Output the data source contents.
|
||||||
*/
|
*/
|
||||||
public class WriteExecuteExchange implements MessageExchange<WriteExecuteExchange.Request, WriteExecuteExchange.Response> {
|
public class WriteExecuteExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
|
|
@ -14,7 +14,7 @@ import lombok.extern.jackson.Jacksonized;
|
||||||
/**
|
/**
|
||||||
* Prepares a client to output the data source contents.
|
* Prepares a client to output the data source contents.
|
||||||
*/
|
*/
|
||||||
public class WritePreparationExchange implements MessageExchange<WritePreparationExchange.Request, WritePreparationExchange.Response> {
|
public class WritePreparationExchange implements MessageExchange {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
|
|
|
@ -29,6 +29,7 @@ module io.xpipe.beacon {
|
||||||
ModeExchange,
|
ModeExchange,
|
||||||
StatusExchange,
|
StatusExchange,
|
||||||
StopExchange,
|
StopExchange,
|
||||||
|
StoreAddExchange,
|
||||||
WritePreparationExchange,
|
WritePreparationExchange,
|
||||||
WriteExecuteExchange,
|
WriteExecuteExchange,
|
||||||
SelectExchange,
|
SelectExchange,
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package io.xpipe.core.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@JsonTypeName("query")
|
||||||
|
@Getter
|
||||||
|
public class BaseQueryElement extends DialogElement {
|
||||||
|
|
||||||
|
private final String description;
|
||||||
|
private final boolean required;
|
||||||
|
protected String value;
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public BaseQueryElement(String description, boolean required, String value) {
|
||||||
|
this.description = description;
|
||||||
|
this.required = required;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
67
core/src/main/java/io/xpipe/core/config/ChoiceElement.java
Normal file
67
core/src/main/java/io/xpipe/core/config/ChoiceElement.java
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
package io.xpipe.core.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Value;
|
||||||
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@JsonTypeName("choice")
|
||||||
|
public class ChoiceElement extends DialogElement {
|
||||||
|
|
||||||
|
private final List<Element> elements;
|
||||||
|
|
||||||
|
private int selected;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(String value) {
|
||||||
|
if (value == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.length() != 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var c = value.charAt(0);
|
||||||
|
if (Character.isDigit(c)) {
|
||||||
|
selected = Integer.parseInt(value) - 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < elements.size(); i++) {
|
||||||
|
if (elements.get(i).getCharacter() != null && elements.get(i).getCharacter().equals(c)) {
|
||||||
|
selected = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Value
|
||||||
|
@Builder
|
||||||
|
@Jacksonized
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class Element {
|
||||||
|
Character character;
|
||||||
|
String description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public ChoiceElement(List<Element> elements, int selected) {
|
||||||
|
this.elements = elements;
|
||||||
|
this.selected = selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Element> getElements() {
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSelected() {
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,10 +17,10 @@ public class ConfigParameter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
ConfigConverter<?> converter;
|
QueryConverter<?> converter;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> ConfigConverter<T> getConverter() {
|
public <T> QueryConverter<T> getConverter() {
|
||||||
return (ConfigConverter<T>) converter;
|
return (QueryConverter<T>) converter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
176
core/src/main/java/io/xpipe/core/config/Dialog.java
Normal file
176
core/src/main/java/io/xpipe/core/config/Dialog.java
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
package io.xpipe.core.config;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public abstract class Dialog {
|
||||||
|
|
||||||
|
private static class Sequence extends Dialog {
|
||||||
|
|
||||||
|
private int index = 0;
|
||||||
|
private final DialogElement[] es;
|
||||||
|
|
||||||
|
public Sequence(DialogElement... es) {
|
||||||
|
this.es = es;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DialogElement start() {
|
||||||
|
index = 0;
|
||||||
|
return es[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DialogElement receive(String answer) {
|
||||||
|
if (es[index].apply(answer)) {
|
||||||
|
if (index == es.length - 1) {
|
||||||
|
complete();
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return es[++index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return es[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dialog chain(DialogElement... es) {
|
||||||
|
return new Dialog.Sequence(es);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dialog chain(Dialog... ds) {
|
||||||
|
return new Dialog() {
|
||||||
|
|
||||||
|
private int current = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DialogElement start() {
|
||||||
|
current = 0;
|
||||||
|
return ds[0].start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DialogElement receive(String answer) {
|
||||||
|
DialogElement currentElement = ds[current].receive(answer);
|
||||||
|
if (currentElement == null) {
|
||||||
|
ds[current].complete();
|
||||||
|
if (current == ds.length - 1) {
|
||||||
|
complete();
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return ds[++current].start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentElement;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dialog of(DialogElement e) {
|
||||||
|
return new Dialog() {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DialogElement start() {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DialogElement receive(String answer) {
|
||||||
|
if (e.apply(answer)) {
|
||||||
|
complete();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dialog retryIf(Dialog d, Supplier<String> msg) {
|
||||||
|
return new Dialog() {
|
||||||
|
|
||||||
|
private boolean retry;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DialogElement start() {
|
||||||
|
return d.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DialogElement receive(String answer) {
|
||||||
|
if (retry) {
|
||||||
|
retry = false;
|
||||||
|
return d.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
var next = d.receive(answer);
|
||||||
|
if (next == null) {
|
||||||
|
var s = msg.get();
|
||||||
|
if (s != null) {
|
||||||
|
retry = true;
|
||||||
|
return new HeaderElement(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
}.evaluateTo(d.onCompletion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Dialog choice(ChoiceElement choice, Function<Integer, Dialog> c) {
|
||||||
|
return new Dialog() {
|
||||||
|
|
||||||
|
private Dialog choiceMade;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DialogElement start() {
|
||||||
|
choiceMade = null;
|
||||||
|
return choice;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DialogElement receive(String answer) {
|
||||||
|
if (choiceMade != null) {
|
||||||
|
var r = choiceMade.receive(answer);
|
||||||
|
if (r == null) {
|
||||||
|
complete();
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (choice.apply(answer)) {
|
||||||
|
choiceMade = c.apply(choice.getSelected());
|
||||||
|
return choiceMade.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
return choice;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object eval;
|
||||||
|
private Supplier<?> onCompletion;
|
||||||
|
|
||||||
|
public abstract DialogElement start();
|
||||||
|
|
||||||
|
public Dialog evaluateTo(Supplier<?> s) {
|
||||||
|
onCompletion = s;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T> T getResult() {
|
||||||
|
return (T) eval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void complete() {
|
||||||
|
if (onCompletion != null) {
|
||||||
|
eval = onCompletion.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract DialogElement receive(String answer);
|
||||||
|
}
|
25
core/src/main/java/io/xpipe/core/config/DialogElement.java
Normal file
25
core/src/main/java/io/xpipe/core/config/DialogElement.java
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
package io.xpipe.core.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
||||||
|
public abstract class DialogElement {
|
||||||
|
|
||||||
|
protected String id;
|
||||||
|
|
||||||
|
public DialogElement() {
|
||||||
|
this.id = UUID.randomUUID().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean apply(String value) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
24
core/src/main/java/io/xpipe/core/config/HeaderElement.java
Normal file
24
core/src/main/java/io/xpipe/core/config/HeaderElement.java
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package io.xpipe.core.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
|
||||||
|
@JsonTypeName("header")
|
||||||
|
public class HeaderElement extends DialogElement {
|
||||||
|
|
||||||
|
protected String header;
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public HeaderElement(String header) {
|
||||||
|
this.header = header;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(String value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHeader() {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,9 +2,9 @@ package io.xpipe.core.config;
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
public abstract class ConfigConverter<T> {
|
public abstract class QueryConverter<T> {
|
||||||
|
|
||||||
public static final ConfigConverter<Charset> CHARSET = new ConfigConverter<Charset>() {
|
public static final QueryConverter<Charset> CHARSET = new QueryConverter<Charset>() {
|
||||||
@Override
|
@Override
|
||||||
protected Charset fromString(String s) {
|
protected Charset fromString(String s) {
|
||||||
return Charset.forName(s);
|
return Charset.forName(s);
|
||||||
|
@ -16,7 +16,7 @@ public abstract class ConfigConverter<T> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final ConfigConverter<String> STRING = new ConfigConverter<String>() {
|
public static final QueryConverter<String> STRING = new QueryConverter<String>() {
|
||||||
@Override
|
@Override
|
||||||
protected String fromString(String s) {
|
protected String fromString(String s) {
|
||||||
return s;
|
return s;
|
||||||
|
@ -28,7 +28,19 @@ public abstract class ConfigConverter<T> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final ConfigConverter<Character> CHARACTER = new ConfigConverter<Character>() {
|
public static final QueryConverter<Integer> INTEGER = new QueryConverter<Integer>() {
|
||||||
|
@Override
|
||||||
|
protected Integer fromString(String s) {
|
||||||
|
return Integer.parseInt(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String toString(Integer value) {
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final QueryConverter<Character> CHARACTER = new QueryConverter<Character>() {
|
||||||
@Override
|
@Override
|
||||||
protected Character fromString(String s) {
|
protected Character fromString(String s) {
|
||||||
if (s.length() != 1) {
|
if (s.length() != 1) {
|
||||||
|
@ -44,7 +56,7 @@ public abstract class ConfigConverter<T> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final ConfigConverter<Boolean> BOOLEAN = new ConfigConverter<Boolean>() {
|
public static final QueryConverter<Boolean> BOOLEAN = new QueryConverter<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
protected Boolean fromString(String s) {
|
protected Boolean fromString(String s) {
|
||||||
if (s.equalsIgnoreCase("y") || s.equalsIgnoreCase("yes") || s.equalsIgnoreCase("true")) {
|
if (s.equalsIgnoreCase("y") || s.equalsIgnoreCase("yes") || s.equalsIgnoreCase("true")) {
|
47
core/src/main/java/io/xpipe/core/config/QueryElement.java
Normal file
47
core/src/main/java/io/xpipe/core/config/QueryElement.java
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package io.xpipe.core.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
|
||||||
|
@JsonSerialize(as = BaseQueryElement.class)
|
||||||
|
public class QueryElement extends BaseQueryElement {
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private final QueryConverter<?> converter;
|
||||||
|
|
||||||
|
public QueryElement(String description, boolean required, String value, QueryConverter<?> converter) {
|
||||||
|
super(description, required, value);
|
||||||
|
this.converter = converter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryElement(String description, boolean required, Object value, QueryConverter<?> converter) {
|
||||||
|
super(description, required, value != null ? value.toString() : null);
|
||||||
|
this.converter = converter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(String value) {
|
||||||
|
if (value == null && this.value != null) {
|
||||||
|
if (isRequired() && this.value == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.value = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
converter.convertFromString(value);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.value = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T> T getConvertedValue() {
|
||||||
|
return (T) converter.convertFromString(value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,8 +38,12 @@ public abstract class DataSource<DS extends DataStore> {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isComplete() {
|
protected boolean supportsRead() {
|
||||||
return true;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean supportsWrite() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,9 +69,13 @@ public abstract class DataSource<DS extends DataStore> {
|
||||||
*/
|
*/
|
||||||
public abstract DataSourceInfo determineInfo() throws Exception;
|
public abstract DataSourceInfo determineInfo() throws Exception;
|
||||||
|
|
||||||
public abstract DataSourceReadConnection openReadConnection() throws Exception;
|
public DataSourceReadConnection openReadConnection() throws Exception {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
public abstract DataSourceConnection openWriteConnection() throws Exception;
|
public DataSourceConnection openWriteConnection() throws Exception {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
public DataSourceConnection openAppendingWriteConnection() throws Exception {
|
public DataSourceConnection openAppendingWriteConnection() throws Exception {
|
||||||
throw new UnsupportedOperationException("Appending write is not supported");
|
throw new UnsupportedOperationException("Appending write is not supported");
|
||||||
|
|
94
core/src/main/java/io/xpipe/core/source/JdbcQuerySource.java
Normal file
94
core/src/main/java/io/xpipe/core/source/JdbcQuerySource.java
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
package io.xpipe.core.source;
|
||||||
|
|
||||||
|
import io.xpipe.core.data.node.*;
|
||||||
|
import io.xpipe.core.data.type.TupleType;
|
||||||
|
import io.xpipe.core.data.type.ValueType;
|
||||||
|
import io.xpipe.core.store.JdbcStore;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public abstract class JdbcQuerySource extends TableDataSource<JdbcStore> {
|
||||||
|
|
||||||
|
JdbcStore store;
|
||||||
|
|
||||||
|
protected abstract String createQuery();
|
||||||
|
|
||||||
|
public Connection createConnection() throws SQLException {
|
||||||
|
return store.createConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean supportsRead() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TableReadConnection newReadConnection() {
|
||||||
|
return new TableReadConnection() {
|
||||||
|
|
||||||
|
private Connection connection;
|
||||||
|
private Statement statement;
|
||||||
|
private TupleType dataType;
|
||||||
|
private ResultSet resultSet;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() throws Exception {
|
||||||
|
connection = createConnection();
|
||||||
|
statement = connection.createStatement();
|
||||||
|
|
||||||
|
resultSet = statement.executeQuery(createQuery());
|
||||||
|
var meta = resultSet.getMetaData();
|
||||||
|
var names = new ArrayList<String>();
|
||||||
|
for (int i = 0; i < meta.getColumnCount(); i++) {
|
||||||
|
names.add(meta.getColumnName(i + 1));
|
||||||
|
}
|
||||||
|
dataType = TupleType.of(names, Collections.nCopies(names.size(), ValueType.of()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws Exception {
|
||||||
|
statement.close();
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TupleType getDataType() {
|
||||||
|
return dataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowCount() throws Exception {
|
||||||
|
return resultSet.getFetchSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void withRows(DataStructureNodeAcceptor<TupleNode> lineAcceptor) throws Exception {
|
||||||
|
while (resultSet.next()) {
|
||||||
|
var vals = new ArrayList<DataStructureNode>();
|
||||||
|
for (int i = 0; i < dataType.getSize(); i++) {
|
||||||
|
vals.add(ValueNode.of(resultSet.getString(i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
var node = TupleNode.of(dataType.getNames(), vals);
|
||||||
|
if (!lineAcceptor.accept(node)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayNode readRows(int maxLines) throws Exception {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ public interface TableReadConnection extends DataSourceReadConnection {
|
||||||
public static TableReadConnection empty() {
|
public static TableReadConnection empty() {
|
||||||
return new TableReadConnection() {
|
return new TableReadConnection() {
|
||||||
@Override
|
@Override
|
||||||
public TupleType getDataType() throws Exception {
|
public TupleType getDataType() {
|
||||||
return TupleType.empty();
|
return TupleType.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ public interface TableReadConnection extends DataSourceReadConnection {
|
||||||
/**
|
/**
|
||||||
* Returns the data type of the table data.
|
* Returns the data type of the table data.
|
||||||
*/
|
*/
|
||||||
TupleType getDataType() throws Exception;
|
TupleType getDataType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the amount of rows to be read or -1 if the amount is unknown.
|
* Returns the amount of rows to be read or -1 if the amount is unknown.
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package io.xpipe.core.store;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.Value;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
@Value
|
||||||
|
@JsonTypeName("commandInput")
|
||||||
|
public class CommandInputStore implements StreamDataStore {
|
||||||
|
|
||||||
|
String cmd;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream openInput() throws Exception {
|
||||||
|
var proc = Runtime.getRuntime().exec(cmd);
|
||||||
|
return proc.getInputStream();
|
||||||
|
}
|
||||||
|
}
|
52
core/src/main/java/io/xpipe/core/store/HttpRequestStore.java
Normal file
52
core/src/main/java/io/xpipe/core/store/HttpRequestStore.java
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
package io.xpipe.core.store;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
|
import lombok.Value;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Value
|
||||||
|
@JsonTypeName("httpRequest")
|
||||||
|
public class HttpRequestStore implements StreamDataStore {
|
||||||
|
|
||||||
|
public static boolean isHttpRequest(String s) {
|
||||||
|
return s.startsWith("http:") || s.startsWith("https:");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<HttpRequestStore> fromString(String s) {
|
||||||
|
try {
|
||||||
|
var uri = new URI(s);
|
||||||
|
return Optional.of(new HttpRequestStore(uri, Map.of()));
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
URI uri;
|
||||||
|
Map<String, String> headers;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream openInput() throws Exception {
|
||||||
|
var b = HttpRequest.newBuilder().uri(uri);
|
||||||
|
headers.forEach(b::setHeader);
|
||||||
|
var req = b.GET().build();
|
||||||
|
|
||||||
|
var client = HttpClient.newHttpClient();
|
||||||
|
var res = client.send(req, HttpResponse.BodyHandlers.ofByteArray());
|
||||||
|
|
||||||
|
return new ByteArrayInputStream(res.body());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean exists() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
34
core/src/main/java/io/xpipe/core/store/JdbcStore.java
Normal file
34
core/src/main/java/io/xpipe/core/store/JdbcStore.java
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package io.xpipe.core.store;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||||
|
@Getter
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@ToString
|
||||||
|
@AllArgsConstructor
|
||||||
|
public abstract class JdbcStore implements DataStore {
|
||||||
|
|
||||||
|
String hostname;
|
||||||
|
int port;
|
||||||
|
|
||||||
|
public void checkConnect() throws Exception {
|
||||||
|
try (Connection con = createConnection()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Connection createConnection() throws SQLException {
|
||||||
|
return DriverManager.getConnection(toUrl(), toProperties());
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String toUrl();
|
||||||
|
|
||||||
|
public abstract Properties toProperties();
|
||||||
|
}
|
|
@ -49,7 +49,9 @@ public interface StreamDataStore extends DataStore {
|
||||||
throw new UnsupportedOperationException("Can't open store output");
|
throw new UnsupportedOperationException("Can't open store output");
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean exists();
|
default boolean exists() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
default boolean persistent() {
|
default boolean persistent() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -11,6 +11,9 @@ import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import com.fasterxml.jackson.databind.jsontype.NamedType;
|
import com.fasterxml.jackson.databind.jsontype.NamedType;
|
||||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||||
|
import io.xpipe.core.config.BaseQueryElement;
|
||||||
|
import io.xpipe.core.config.ChoiceElement;
|
||||||
|
import io.xpipe.core.config.HeaderElement;
|
||||||
import io.xpipe.core.data.type.ArrayType;
|
import io.xpipe.core.data.type.ArrayType;
|
||||||
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;
|
||||||
|
@ -18,6 +21,7 @@ import io.xpipe.core.data.type.WildcardType;
|
||||||
import io.xpipe.core.source.DataSourceInfo;
|
import io.xpipe.core.source.DataSourceInfo;
|
||||||
import io.xpipe.core.source.DataSourceReference;
|
import io.xpipe.core.source.DataSourceReference;
|
||||||
import io.xpipe.core.store.CollectionEntryDataStore;
|
import io.xpipe.core.store.CollectionEntryDataStore;
|
||||||
|
import io.xpipe.core.store.HttpRequestStore;
|
||||||
import io.xpipe.core.store.LocalDirectoryDataStore;
|
import io.xpipe.core.store.LocalDirectoryDataStore;
|
||||||
import io.xpipe.core.store.LocalFileDataStore;
|
import io.xpipe.core.store.LocalFileDataStore;
|
||||||
|
|
||||||
|
@ -33,6 +37,7 @@ public class CoreJacksonModule extends SimpleModule {
|
||||||
new NamedType(LocalFileDataStore.class),
|
new NamedType(LocalFileDataStore.class),
|
||||||
new NamedType(LocalDirectoryDataStore.class),
|
new NamedType(LocalDirectoryDataStore.class),
|
||||||
new NamedType(CollectionEntryDataStore.class),
|
new NamedType(CollectionEntryDataStore.class),
|
||||||
|
new NamedType(HttpRequestStore.class),
|
||||||
new NamedType(ValueType.class),
|
new NamedType(ValueType.class),
|
||||||
new NamedType(TupleType.class),
|
new NamedType(TupleType.class),
|
||||||
new NamedType(ArrayType.class),
|
new NamedType(ArrayType.class),
|
||||||
|
@ -41,7 +46,10 @@ public class CoreJacksonModule extends SimpleModule {
|
||||||
new NamedType(DataSourceInfo.Structure.class),
|
new NamedType(DataSourceInfo.Structure.class),
|
||||||
new NamedType(DataSourceInfo.Text.class),
|
new NamedType(DataSourceInfo.Text.class),
|
||||||
new NamedType(DataSourceInfo.Collection.class),
|
new NamedType(DataSourceInfo.Collection.class),
|
||||||
new NamedType(DataSourceInfo.Raw.class)
|
new NamedType(DataSourceInfo.Raw.class),
|
||||||
|
new NamedType(BaseQueryElement.class),
|
||||||
|
new NamedType(ChoiceElement.class),
|
||||||
|
new NamedType(HeaderElement.class)
|
||||||
);
|
);
|
||||||
|
|
||||||
addSerializer(Charset.class, new CharsetSerializer());
|
addSerializer(Charset.class, new CharsetSerializer());
|
||||||
|
|
|
@ -22,7 +22,9 @@ module io.xpipe.core {
|
||||||
|
|
||||||
requires com.fasterxml.jackson.core;
|
requires com.fasterxml.jackson.core;
|
||||||
requires com.fasterxml.jackson.databind;
|
requires com.fasterxml.jackson.databind;
|
||||||
|
requires java.net.http;
|
||||||
requires static lombok;
|
requires static lombok;
|
||||||
|
requires java.sql;
|
||||||
|
|
||||||
uses com.fasterxml.jackson.databind.Module;
|
uses com.fasterxml.jackson.databind.Module;
|
||||||
provides com.fasterxml.jackson.databind.Module with CoreJacksonModule;
|
provides com.fasterxml.jackson.databind.Module with CoreJacksonModule;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package io.xpipe.extension;
|
package io.xpipe.extension;
|
||||||
|
|
||||||
import io.xpipe.charsetter.NewLine;
|
import io.xpipe.charsetter.NewLine;
|
||||||
import io.xpipe.core.config.ConfigConverter;
|
import io.xpipe.core.config.QueryConverter;
|
||||||
import io.xpipe.core.config.ConfigParameter;
|
import io.xpipe.core.config.ConfigParameter;
|
||||||
import io.xpipe.core.source.DataSource;
|
import io.xpipe.core.source.DataSource;
|
||||||
import io.xpipe.core.source.DataSourceType;
|
import io.xpipe.core.source.DataSourceType;
|
||||||
|
@ -9,7 +9,6 @@ import io.xpipe.core.store.DataStore;
|
||||||
import javafx.beans.property.Property;
|
import javafx.beans.property.Property;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.Value;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -93,13 +92,6 @@ public interface DataSourceProvider<T extends DataSource<?>> {
|
||||||
|
|
||||||
interface ConfigProvider<T extends DataSource<?>> {
|
interface ConfigProvider<T extends DataSource<?>> {
|
||||||
|
|
||||||
@Value
|
|
||||||
static class Parameter {
|
|
||||||
ConfigParameter parameter;
|
|
||||||
Object currentValue;
|
|
||||||
boolean required;
|
|
||||||
}
|
|
||||||
|
|
||||||
static <T extends DataSource<?>> ConfigProvider<T> empty(List<String> names, Function<DataStore, T> func) {
|
static <T extends DataSource<?>> ConfigProvider<T> empty(List<String> names, Function<DataStore, T> func) {
|
||||||
return new ConfigProvider<>() {
|
return new ConfigProvider<>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -124,9 +116,9 @@ public interface DataSourceProvider<T extends DataSource<?>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigParameter CHARSET = new ConfigParameter(
|
ConfigParameter CHARSET = new ConfigParameter(
|
||||||
"charset", ConfigConverter.CHARSET);
|
"charset", QueryConverter.CHARSET);
|
||||||
|
|
||||||
public static final ConfigConverter<NewLine> NEW_LINE_CONVERTER = new ConfigConverter<NewLine>() {
|
public static final QueryConverter<NewLine> NEW_LINE_CONVERTER = new QueryConverter<NewLine>() {
|
||||||
@Override
|
@Override
|
||||||
protected NewLine fromString(String s) {
|
protected NewLine fromString(String s) {
|
||||||
return NewLine.id(s);
|
return NewLine.id(s);
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package io.xpipe.extension;
|
||||||
|
|
||||||
|
import io.xpipe.core.config.Dialog;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface DataStoreProvider {
|
||||||
|
|
||||||
|
default void init() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
default String i18n(String key) {
|
||||||
|
return I18n.get(getId() + "." + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
default String i18nKey(String key) {
|
||||||
|
return getId() + "." + key;
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getDisplayName() {
|
||||||
|
return i18n("displayName");
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getDisplayDescription() {
|
||||||
|
return i18n("displayDescription");
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getDisplayIconFileName() {
|
||||||
|
return getId() + ":icon.png";
|
||||||
|
}
|
||||||
|
|
||||||
|
default Dialog dialogForURL(URL url) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dialog defaultDialog();
|
||||||
|
|
||||||
|
List<String> getPossibleNames();
|
||||||
|
|
||||||
|
default String getId() {
|
||||||
|
var n = getClass().getPackageName();
|
||||||
|
var i = n.lastIndexOf('.');
|
||||||
|
return i != -1 ? n.substring(i + 1) : n;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package io.xpipe.extension;
|
||||||
|
|
||||||
|
import io.xpipe.core.config.Dialog;
|
||||||
|
import io.xpipe.extension.event.ErrorEvent;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class DataStoreProviders {
|
||||||
|
|
||||||
|
private static Set<DataStoreProvider> ALL;
|
||||||
|
|
||||||
|
public static void init(ModuleLayer layer) {
|
||||||
|
if (ALL == null) {
|
||||||
|
ALL = ServiceLoader.load(layer, DataStoreProvider.class).stream()
|
||||||
|
.map(p -> (DataStoreProvider) p.get()).collect(Collectors.toSet());
|
||||||
|
ALL.forEach(p -> {
|
||||||
|
try {
|
||||||
|
p.init();
|
||||||
|
} catch (Exception e) {
|
||||||
|
ErrorEvent.fromThrowable(e).handle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<DataStoreProvider> byName(String name) {
|
||||||
|
if (ALL == null) {
|
||||||
|
throw new IllegalStateException("Not initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ALL.stream().filter(d -> d.getPossibleNames().stream()
|
||||||
|
.anyMatch(s -> s.equalsIgnoreCase(name))).findAny();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<Dialog> byURL(URL url) {
|
||||||
|
if (ALL == null) {
|
||||||
|
throw new IllegalStateException("Not initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ALL.stream().map(d -> d.dialogForURL(url)).filter(Objects::nonNull).findAny();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<DataStoreProvider> getAll() {
|
||||||
|
return ALL;
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,4 +35,5 @@ module io.xpipe.extension {
|
||||||
uses io.xpipe.extension.I18n;
|
uses io.xpipe.extension.I18n;
|
||||||
uses io.xpipe.extension.event.EventHandler;
|
uses io.xpipe.extension.event.EventHandler;
|
||||||
uses io.xpipe.extension.prefs.PrefsProvider;
|
uses io.xpipe.extension.prefs.PrefsProvider;
|
||||||
|
uses io.xpipe.extension.DataStoreProvider;
|
||||||
}
|
}
|
Loading…
Reference in a new issue