From e5a84a83dbbb3bdcdd8ac433ef075865769ec98d Mon Sep 17 00:00:00 2001 From: Christopher Schnick Date: Sun, 2 Jan 2022 23:13:10 +0100 Subject: [PATCH] Small fixes --- .../java/io/xpipe/api/XPipeApiConnector.java | 15 ++++---- .../java/io/xpipe/api/XPipeException.java | 23 ++++++++++++ .../io/xpipe/api/impl/DataSourceImpl.java | 9 +++-- .../java/io/xpipe/beacon/BeaconConnector.java | 5 +++ .../java/io/xpipe/beacon/BeaconHandler.java | 2 +- .../exchange/StoreResourceExchange.java | 2 +- beacon/src/main/java/module-info.java | 1 + .../io/xpipe/core/source/DataSourceId.java | 15 ++++---- .../io/xpipe/core/util/JacksonHelper.java | 4 +++ .../xpipe/extension/DataSourceProviders.java | 15 ++++++++ library/build.gradle | 16 ++++----- library/module-info.java | 35 ++++++++++++++++--- samples/sample_program/build.gradle | 11 ++++-- .../io/xpipe/sample/HomePricesSample.java | 2 +- .../src/main/java/module-info.java | 2 +- 15 files changed, 120 insertions(+), 37 deletions(-) create mode 100644 api/src/main/java/io/xpipe/api/XPipeException.java diff --git a/api/src/main/java/io/xpipe/api/XPipeApiConnector.java b/api/src/main/java/io/xpipe/api/XPipeApiConnector.java index bfe314dbe..c9c8c456a 100644 --- a/api/src/main/java/io/xpipe/api/XPipeApiConnector.java +++ b/api/src/main/java/io/xpipe/api/XPipeApiConnector.java @@ -1,6 +1,7 @@ package io.xpipe.api; import io.xpipe.beacon.*; +import io.xpipe.core.util.JacksonHelper; import java.util.Optional; @@ -10,14 +11,8 @@ public abstract class XPipeApiConnector extends BeaconConnector { try { var socket = constructSocket(); handle(socket); - } catch (ConnectorException ce) { - throw new XPipeConnectException(ce.getMessage()); - } catch (ClientException ce) { - throw new XPipeClientException(ce.getMessage()); - } catch (ServerException se) { - throw new XPipeServerException(se.getMessage()); - } catch (Throwable t) { - throw new XPipeConnectException(t); + } catch (Throwable ce) { + throw new XPipeException(ce); } } @@ -25,6 +20,10 @@ public abstract class XPipeApiConnector extends BeaconConnector { @Override protected BeaconClient constructSocket() throws ConnectorException { + if (!JacksonHelper.isInit()) { + JacksonHelper.init(ModuleLayer.boot()); + } + if (!BeaconServer.isRunning()) { try { start(); diff --git a/api/src/main/java/io/xpipe/api/XPipeException.java b/api/src/main/java/io/xpipe/api/XPipeException.java new file mode 100644 index 000000000..d5b62bebd --- /dev/null +++ b/api/src/main/java/io/xpipe/api/XPipeException.java @@ -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); + } +} diff --git a/api/src/main/java/io/xpipe/api/impl/DataSourceImpl.java b/api/src/main/java/io/xpipe/api/impl/DataSourceImpl.java index 64cc12a58..4484281fb 100644 --- a/api/src/main/java/io/xpipe/api/impl/DataSourceImpl.java +++ b/api/src/main/java/io/xpipe/api/impl/DataSourceImpl.java @@ -46,8 +46,13 @@ public abstract class DataSourceImpl implements DataSource { @Override protected void handle(BeaconClient sc) throws ClientException, ServerException, ConnectorException { var req = StoreResourceExchange.Request.builder() - .url(url).type(type).build(); - StoreResourceExchange.Response res = performSimpleExchange(sc, req); + .url(url).providerId(type).build(); + StoreResourceExchange.Response res = performOutputExchange(sc, req, out -> { + try (var s = url.openStream()) { + writeLength(sc, s.available()); + s.transferTo(out); + } + }); switch (res.getSourceType()) { case TABLE -> { var data = res.getTableData(); diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconConnector.java b/beacon/src/main/java/io/xpipe/beacon/BeaconConnector.java index a43fb2b81..5e6e96ab6 100644 --- a/beacon/src/main/java/io/xpipe/beacon/BeaconConnector.java +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconConnector.java @@ -6,6 +6,7 @@ import io.xpipe.beacon.message.ResponseMessage; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.ByteBuffer; import java.util.concurrent.atomic.AtomicReference; public abstract class BeaconConnector { @@ -40,6 +41,10 @@ public abstract class BeaconConnector { return response.get(); } + protected void writeLength(BeaconClient socket, int bytes) throws IOException { + socket.getOutputStream().write(ByteBuffer.allocate(4).putInt(bytes).array()); + } + protected RES performSimpleExchange( BeaconClient socket, REQ req) throws ServerException, ConnectorException, ClientException { diff --git a/beacon/src/main/java/io/xpipe/beacon/BeaconHandler.java b/beacon/src/main/java/io/xpipe/beacon/BeaconHandler.java index 4a307736a..ca7a3f7b6 100644 --- a/beacon/src/main/java/io/xpipe/beacon/BeaconHandler.java +++ b/beacon/src/main/java/io/xpipe/beacon/BeaconHandler.java @@ -10,7 +10,7 @@ public interface BeaconHandler { void prepareBody() throws IOException; - void startBodyRead() throws IOException; + InputStream startBodyRead() throws IOException; public void sendResponse(T obj) throws Exception; diff --git a/beacon/src/main/java/io/xpipe/beacon/exchange/StoreResourceExchange.java b/beacon/src/main/java/io/xpipe/beacon/exchange/StoreResourceExchange.java index 07ee329b7..ed4ed3567 100644 --- a/beacon/src/main/java/io/xpipe/beacon/exchange/StoreResourceExchange.java +++ b/beacon/src/main/java/io/xpipe/beacon/exchange/StoreResourceExchange.java @@ -33,7 +33,7 @@ public class StoreResourceExchange implements MessageExchange d.supportsFile(file)).findAny(); } + public static Optional 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 getAll() { return ALL; } diff --git a/library/build.gradle b/library/build.gradle index 38ff2f3da..7edfcec58 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -36,24 +36,24 @@ sourceSets { java { srcDir(projectDir) - srcDir("$rootDir/api/src/main/java") + srcDir("../api/src/main/java") 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 { - 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 { - 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 { - return it.getFile() == file("$rootDir/extension/src/main/java/module-info.java") + return it.getFile() == file("../extension/src/main/java/module-info.java") } } } diff --git a/library/module-info.java b/library/module-info.java index d92f44954..c23c12ea1 100644 --- a/library/module-info.java +++ b/library/module-info.java @@ -1,9 +1,40 @@ module io.xpipe { + // api exports io.xpipe.api; + // beacon exports io.xpipe.beacon; exports io.xpipe.beacon.exchange; 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.databind; @@ -11,8 +42,4 @@ module io.xpipe { requires static lombok; requires static javafx.base; requires static javafx.graphics; - - opens io.xpipe.beacon; - opens io.xpipe.beacon.exchange; - opens io.xpipe.beacon.message; } \ No newline at end of file diff --git a/samples/sample_program/build.gradle b/samples/sample_program/build.gradle index 9b3a01aa9..07de0fada 100644 --- a/samples/sample_program/build.gradle +++ b/samples/sample_program/build.gradle @@ -11,8 +11,15 @@ java { repositories { mavenCentral() } +apply from: "$rootDir/deps/jackson.gradle" dependencies { - implementation project(':api') - implementation project(':core') + implementation files(project(':library').jar.archivePath) +} + +compileJava.dependsOn(project(':library').jar) + +application { + mainModule = 'io.xpipe.sample' + mainClass = 'io.xpipe.sample.HomePricesSample' } \ No newline at end of file diff --git a/samples/sample_program/src/main/java/io/xpipe/sample/HomePricesSample.java b/samples/sample_program/src/main/java/io/xpipe/sample/HomePricesSample.java index 56406c2ba..3fee73681 100644 --- a/samples/sample_program/src/main/java/io/xpipe/sample/HomePricesSample.java +++ b/samples/sample_program/src/main/java/io/xpipe/sample/HomePricesSample.java @@ -17,7 +17,7 @@ public class HomePricesSample { // Note that while this is possible, it is not recommended as // all queries are routed through the XPipe client anyway. // 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 // the correct configuration parameters. You can access these parameters like this: diff --git a/samples/sample_program/src/main/java/module-info.java b/samples/sample_program/src/main/java/module-info.java index f9254c169..5d464dc91 100644 --- a/samples/sample_program/src/main/java/module-info.java +++ b/samples/sample_program/src/main/java/module-info.java @@ -1,3 +1,3 @@ module io.xpipe.sample { - requires io.xpipe.api; + requires io.xpipe; } \ No newline at end of file