mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-21 15:10:23 +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;
|
||||
|
||||
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();
|
||||
|
|
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
|
||||
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();
|
||||
|
|
|
@ -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 <REQ extends RequestMessage, RES extends ResponseMessage> RES performSimpleExchange(
|
||||
BeaconClient socket,
|
||||
REQ req) throws ServerException, ConnectorException, ClientException {
|
||||
|
|
|
@ -10,7 +10,7 @@ public interface BeaconHandler {
|
|||
|
||||
void prepareBody() throws IOException;
|
||||
|
||||
void startBodyRead() throws IOException;
|
||||
InputStream startBodyRead() throws IOException;
|
||||
|
||||
public <T extends ResponseMessage> void sendResponse(T obj) throws Exception;
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ public class StoreResourceExchange implements MessageExchange<StoreResourceExcha
|
|||
@Value
|
||||
public static class Request implements RequestMessage {
|
||||
URL url;
|
||||
String type;
|
||||
String providerId;
|
||||
}
|
||||
|
||||
@Jacksonized
|
||||
|
|
|
@ -26,5 +26,6 @@ module io.xpipe.beacon {
|
|||
ReadInfoExchange,
|
||||
StatusExchange,
|
||||
StopExchange,
|
||||
StoreResourceExchange,
|
||||
VersionExchange;
|
||||
}
|
|
@ -12,6 +12,8 @@ import lombok.Getter;
|
|||
* 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.
|
||||
*
|
||||
* A missing collection name indicates that the data source exists only temporarily.
|
||||
*
|
||||
* @see #create(String, 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.
|
||||
*
|
||||
* @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
|
||||
* @throws IllegalArgumentException if any name is not valid
|
||||
*/
|
||||
public static DataSourceId create(String collectionName, String entryName) {
|
||||
if (collectionName == null) {
|
||||
throw new IllegalArgumentException("Collection name is null");
|
||||
}
|
||||
if (collectionName.trim().length() == 0) {
|
||||
if (collectionName != null && collectionName.trim().length() == 0) {
|
||||
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");
|
||||
}
|
||||
|
||||
|
@ -78,9 +77,7 @@ public class DataSourceId {
|
|||
|
||||
var cn = split[0].trim().toLowerCase();
|
||||
var en = split[1].trim().toLowerCase();
|
||||
if (cn.length() == 0) {
|
||||
throw new IllegalArgumentException("Collection name must not be empty");
|
||||
}
|
||||
cn = cn.isEmpty() ? null : cn;
|
||||
if (en.length() == 0) {
|
||||
throw new IllegalArgumentException("Entry name must not be empty");
|
||||
}
|
||||
|
|
|
@ -44,4 +44,8 @@ public class JacksonHelper {
|
|||
|
||||
return INSTANCE.copy();
|
||||
}
|
||||
|
||||
public static boolean isInit() {
|
||||
return init;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package io.xpipe.extension;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.ServiceLoader;
|
||||
|
@ -41,6 +43,19 @@ public class DataSourceProviders {
|
|||
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() {
|
||||
return ALL;
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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'
|
||||
}
|
|
@ -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:
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
module io.xpipe.sample {
|
||||
requires io.xpipe.api;
|
||||
requires io.xpipe;
|
||||
}
|
Loading…
Reference in a new issue