mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 09:00:26 +00:00
Small fixes
This commit is contained in:
parent
8bb6f8be3d
commit
e5a84a83db
15 changed files with 120 additions and 37 deletions
|
@ -1,6 +1,7 @@
|
||||||
package io.xpipe.api;
|
package io.xpipe.api;
|
||||||
|
|
||||||
import io.xpipe.beacon.*;
|
import io.xpipe.beacon.*;
|
||||||
|
import io.xpipe.core.util.JacksonHelper;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@ -10,14 +11,8 @@ public abstract class XPipeApiConnector extends BeaconConnector {
|
||||||
try {
|
try {
|
||||||
var socket = constructSocket();
|
var socket = constructSocket();
|
||||||
handle(socket);
|
handle(socket);
|
||||||
} catch (ConnectorException ce) {
|
} catch (Throwable ce) {
|
||||||
throw new XPipeConnectException(ce.getMessage());
|
throw new XPipeException(ce);
|
||||||
} catch (ClientException ce) {
|
|
||||||
throw new XPipeClientException(ce.getMessage());
|
|
||||||
} catch (ServerException se) {
|
|
||||||
throw new XPipeServerException(se.getMessage());
|
|
||||||
} catch (Throwable t) {
|
|
||||||
throw new XPipeConnectException(t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +20,10 @@ public abstract class XPipeApiConnector extends BeaconConnector {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected BeaconClient constructSocket() throws ConnectorException {
|
protected BeaconClient constructSocket() throws ConnectorException {
|
||||||
|
if (!JacksonHelper.isInit()) {
|
||||||
|
JacksonHelper.init(ModuleLayer.boot());
|
||||||
|
}
|
||||||
|
|
||||||
if (!BeaconServer.isRunning()) {
|
if (!BeaconServer.isRunning()) {
|
||||||
try {
|
try {
|
||||||
start();
|
start();
|
||||||
|
|
23
api/src/main/java/io/xpipe/api/XPipeException.java
Normal file
23
api/src/main/java/io/xpipe/api/XPipeException.java
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package io.xpipe.api;
|
||||||
|
|
||||||
|
public class XPipeException extends RuntimeException {
|
||||||
|
|
||||||
|
public XPipeException() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public XPipeException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public XPipeException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public XPipeException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public XPipeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||||
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,8 +46,13 @@ public abstract class DataSourceImpl implements DataSource {
|
||||||
@Override
|
@Override
|
||||||
protected void handle(BeaconClient sc) throws ClientException, ServerException, ConnectorException {
|
protected void handle(BeaconClient sc) throws ClientException, ServerException, ConnectorException {
|
||||||
var req = StoreResourceExchange.Request.builder()
|
var req = StoreResourceExchange.Request.builder()
|
||||||
.url(url).type(type).build();
|
.url(url).providerId(type).build();
|
||||||
StoreResourceExchange.Response res = performSimpleExchange(sc, req);
|
StoreResourceExchange.Response res = performOutputExchange(sc, req, out -> {
|
||||||
|
try (var s = url.openStream()) {
|
||||||
|
writeLength(sc, s.available());
|
||||||
|
s.transferTo(out);
|
||||||
|
}
|
||||||
|
});
|
||||||
switch (res.getSourceType()) {
|
switch (res.getSourceType()) {
|
||||||
case TABLE -> {
|
case TABLE -> {
|
||||||
var data = res.getTableData();
|
var data = res.getTableData();
|
||||||
|
|
|
@ -6,6 +6,7 @@ import io.xpipe.beacon.message.ResponseMessage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
public abstract class BeaconConnector {
|
public abstract class BeaconConnector {
|
||||||
|
@ -40,6 +41,10 @@ public abstract class BeaconConnector {
|
||||||
return response.get();
|
return response.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void writeLength(BeaconClient socket, int bytes) throws IOException {
|
||||||
|
socket.getOutputStream().write(ByteBuffer.allocate(4).putInt(bytes).array());
|
||||||
|
}
|
||||||
|
|
||||||
protected <REQ extends RequestMessage, RES extends ResponseMessage> RES performSimpleExchange(
|
protected <REQ extends RequestMessage, RES extends ResponseMessage> RES performSimpleExchange(
|
||||||
BeaconClient socket,
|
BeaconClient socket,
|
||||||
REQ req) throws ServerException, ConnectorException, ClientException {
|
REQ req) throws ServerException, ConnectorException, ClientException {
|
||||||
|
|
|
@ -10,7 +10,7 @@ public interface BeaconHandler {
|
||||||
|
|
||||||
void prepareBody() throws IOException;
|
void prepareBody() throws IOException;
|
||||||
|
|
||||||
void startBodyRead() throws IOException;
|
InputStream startBodyRead() throws IOException;
|
||||||
|
|
||||||
public <T extends ResponseMessage> void sendResponse(T obj) throws Exception;
|
public <T extends ResponseMessage> void sendResponse(T obj) throws Exception;
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class StoreResourceExchange implements MessageExchange<StoreResourceExcha
|
||||||
@Value
|
@Value
|
||||||
public static class Request implements RequestMessage {
|
public static class Request implements RequestMessage {
|
||||||
URL url;
|
URL url;
|
||||||
String type;
|
String providerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
|
|
|
@ -26,5 +26,6 @@ module io.xpipe.beacon {
|
||||||
ReadInfoExchange,
|
ReadInfoExchange,
|
||||||
StatusExchange,
|
StatusExchange,
|
||||||
StopExchange,
|
StopExchange,
|
||||||
|
StoreResourceExchange,
|
||||||
VersionExchange;
|
VersionExchange;
|
||||||
}
|
}
|
|
@ -12,6 +12,8 @@ import lombok.Getter;
|
||||||
* 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.
|
||||||
*
|
*
|
||||||
|
* A missing collection name indicates that the data source exists only temporarily.
|
||||||
|
*
|
||||||
* @see #create(String, String)
|
* @see #create(String, String)
|
||||||
* @see #fromString(String)
|
* @see #fromString(String)
|
||||||
*/
|
*/
|
||||||
|
@ -31,18 +33,15 @@ public class DataSourceId {
|
||||||
/**
|
/**
|
||||||
* Creates a new data source id from a collection name and an entry name.
|
* Creates a new data source id from a collection name and an entry name.
|
||||||
*
|
*
|
||||||
* @param collectionName the collection name, which must be not null and not empty
|
* @param collectionName the collection name, which may be null but not an empty string
|
||||||
* @param entryName the entry name, which must be not null and not empty
|
* @param entryName the entry name, which must be not null and not empty
|
||||||
* @throws IllegalArgumentException if any name is not valid
|
* @throws IllegalArgumentException if any name is not valid
|
||||||
*/
|
*/
|
||||||
public static DataSourceId create(String collectionName, String entryName) {
|
public static DataSourceId create(String collectionName, String entryName) {
|
||||||
if (collectionName == null) {
|
if (collectionName != null && collectionName.trim().length() == 0) {
|
||||||
throw new IllegalArgumentException("Collection name is null");
|
|
||||||
}
|
|
||||||
if (collectionName.trim().length() == 0) {
|
|
||||||
throw new IllegalArgumentException("Trimmed collection name is empty");
|
throw new IllegalArgumentException("Trimmed collection name is empty");
|
||||||
}
|
}
|
||||||
if (collectionName.contains("" + SEPARATOR)) {
|
if (collectionName != null && collectionName.contains("" + SEPARATOR)) {
|
||||||
throw new IllegalArgumentException("Separator character " + SEPARATOR + " is not allowed in the collection name");
|
throw new IllegalArgumentException("Separator character " + SEPARATOR + " is not allowed in the collection name");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,9 +77,7 @@ public class DataSourceId {
|
||||||
|
|
||||||
var cn = split[0].trim().toLowerCase();
|
var cn = split[0].trim().toLowerCase();
|
||||||
var en = split[1].trim().toLowerCase();
|
var en = split[1].trim().toLowerCase();
|
||||||
if (cn.length() == 0) {
|
cn = cn.isEmpty() ? null : cn;
|
||||||
throw new IllegalArgumentException("Collection name must not be empty");
|
|
||||||
}
|
|
||||||
if (en.length() == 0) {
|
if (en.length() == 0) {
|
||||||
throw new IllegalArgumentException("Entry name must not be empty");
|
throw new IllegalArgumentException("Entry name must not be empty");
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,4 +44,8 @@ public class JacksonHelper {
|
||||||
|
|
||||||
return INSTANCE.copy();
|
return INSTANCE.copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isInit() {
|
||||||
|
return init;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package io.xpipe.extension;
|
package io.xpipe.extension;
|
||||||
|
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
|
@ -41,6 +43,19 @@ public class DataSourceProviders {
|
||||||
return ALL.stream().filter(d -> d.supportsFile(file)).findAny();
|
return ALL.stream().filter(d -> d.supportsFile(file)).findAny();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Optional<DataSourceProvider> byURL(URL url) {
|
||||||
|
if (ALL == null) {
|
||||||
|
throw new IllegalStateException("Not initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
var path = Path.of(url.toURI());
|
||||||
|
return byFile(path);
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Set<DataSourceProvider> getAll() {
|
public static Set<DataSourceProvider> getAll() {
|
||||||
return ALL;
|
return ALL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,24 +36,24 @@ sourceSets {
|
||||||
java {
|
java {
|
||||||
srcDir(projectDir)
|
srcDir(projectDir)
|
||||||
|
|
||||||
srcDir("$rootDir/api/src/main/java")
|
srcDir("../api/src/main/java")
|
||||||
exclude {
|
exclude {
|
||||||
return it.getFile() == file("$rootDir/api/src/main/java/module-info.java")
|
return it.getFile() == file("../api/src/main/java/module-info.java")
|
||||||
}
|
}
|
||||||
|
|
||||||
srcDir("$rootDir/core/src/main/java")
|
srcDir("../core/src/main/java")
|
||||||
exclude {
|
exclude {
|
||||||
return it.getFile() == file("$rootDir/core/src/main/java/module-info.java")
|
return it.getFile() == file("../core/src/main/java/module-info.java")
|
||||||
}
|
}
|
||||||
|
|
||||||
srcDir("$rootDir/beacon/src/main/java")
|
srcDir("../beacon/src/main/java")
|
||||||
exclude {
|
exclude {
|
||||||
return it.getFile() == file("$rootDir/beacon/src/main/java/module-info.java")
|
return it.getFile() == file("../beacon/src/main/java/module-info.java")
|
||||||
}
|
}
|
||||||
|
|
||||||
srcDir("$rootDir/extension/src/main/java")
|
srcDir("../extension/src/main/java")
|
||||||
exclude {
|
exclude {
|
||||||
return it.getFile() == file("$rootDir/extension/src/main/java/module-info.java")
|
return it.getFile() == file("../extension/src/main/java/module-info.java")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,40 @@
|
||||||
module io.xpipe {
|
module io.xpipe {
|
||||||
|
// api
|
||||||
exports io.xpipe.api;
|
exports io.xpipe.api;
|
||||||
|
|
||||||
|
// beacon
|
||||||
exports io.xpipe.beacon;
|
exports io.xpipe.beacon;
|
||||||
exports io.xpipe.beacon.exchange;
|
exports io.xpipe.beacon.exchange;
|
||||||
exports io.xpipe.beacon.message;
|
exports io.xpipe.beacon.message;
|
||||||
|
opens io.xpipe.beacon;
|
||||||
|
opens io.xpipe.beacon.exchange;
|
||||||
|
opens io.xpipe.beacon.message;
|
||||||
|
uses io.xpipe.beacon.exchange.MessageExchange;
|
||||||
|
provides io.xpipe.beacon.exchange.MessageExchange with
|
||||||
|
io.xpipe.beacon.exchange.ListCollectionsExchange,
|
||||||
|
io.xpipe.beacon.exchange.ListEntriesExchange,
|
||||||
|
io.xpipe.beacon.exchange.ReadTableDataExchange,
|
||||||
|
io.xpipe.beacon.exchange.ReadInfoExchange,
|
||||||
|
io.xpipe.beacon.exchange.StatusExchange,
|
||||||
|
io.xpipe.beacon.exchange.StopExchange,
|
||||||
|
io.xpipe.beacon.exchange.StoreResourceExchange,
|
||||||
|
io.xpipe.beacon.exchange.VersionExchange;
|
||||||
|
|
||||||
|
// core
|
||||||
|
exports io.xpipe.core.store;
|
||||||
|
exports io.xpipe.core.source;
|
||||||
|
exports io.xpipe.core.data.generic;
|
||||||
|
exports io.xpipe.core.data.type;
|
||||||
|
exports io.xpipe.core.data.node;
|
||||||
|
exports io.xpipe.core.util;
|
||||||
|
exports io.xpipe.core.data.typed;
|
||||||
|
opens io.xpipe.core.store;
|
||||||
|
opens io.xpipe.core.source;
|
||||||
|
opens io.xpipe.core.data.typed;
|
||||||
|
|
||||||
|
// core services
|
||||||
|
uses com.fasterxml.jackson.databind.Module;
|
||||||
|
provides com.fasterxml.jackson.databind.Module with io.xpipe.core.util.CoreJacksonModule;
|
||||||
|
|
||||||
requires com.fasterxml.jackson.core;
|
requires com.fasterxml.jackson.core;
|
||||||
requires com.fasterxml.jackson.databind;
|
requires com.fasterxml.jackson.databind;
|
||||||
|
@ -11,8 +42,4 @@ module io.xpipe {
|
||||||
requires static lombok;
|
requires static lombok;
|
||||||
requires static javafx.base;
|
requires static javafx.base;
|
||||||
requires static javafx.graphics;
|
requires static javafx.graphics;
|
||||||
|
|
||||||
opens io.xpipe.beacon;
|
|
||||||
opens io.xpipe.beacon.exchange;
|
|
||||||
opens io.xpipe.beacon.message;
|
|
||||||
}
|
}
|
|
@ -11,8 +11,15 @@ java {
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
apply from: "$rootDir/deps/jackson.gradle"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':api')
|
implementation files(project(':library').jar.archivePath)
|
||||||
implementation project(':core')
|
}
|
||||||
|
|
||||||
|
compileJava.dependsOn(project(':library').jar)
|
||||||
|
|
||||||
|
application {
|
||||||
|
mainModule = 'io.xpipe.sample'
|
||||||
|
mainClass = 'io.xpipe.sample.HomePricesSample'
|
||||||
}
|
}
|
|
@ -17,7 +17,7 @@ public class HomePricesSample {
|
||||||
// Note that while this is possible, it is not recommended as
|
// Note that while this is possible, it is not recommended as
|
||||||
// all queries are routed through the XPipe client anyway.
|
// all queries are routed through the XPipe client anyway.
|
||||||
// It allows us however to bundle the data with this sample program.
|
// It allows us however to bundle the data with this sample program.
|
||||||
homePricesTable = DataSource.wrap(resource).asTable();
|
homePricesTable = DataSource.wrap(resource, "csv").asTable();
|
||||||
|
|
||||||
// As we didn't pass any configuration parameters, X-Pipe will try to automatically detect
|
// As we didn't pass any configuration parameters, X-Pipe will try to automatically detect
|
||||||
// the correct configuration parameters. You can access these parameters like this:
|
// the correct configuration parameters. You can access these parameters like this:
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
module io.xpipe.sample {
|
module io.xpipe.sample {
|
||||||
requires io.xpipe.api;
|
requires io.xpipe;
|
||||||
}
|
}
|
Loading…
Reference in a new issue