From c4f76b2af8dc9549c5cbecdcead3576baf2a07e5 Mon Sep 17 00:00:00 2001 From: Nick Molcanov <32801560+nck-mlcnv@users.noreply.github.com> Date: Wed, 30 Aug 2023 16:48:20 +0200 Subject: [PATCH] add missing separator configuration for query files * also delegate the deserializer class for the QueryHandler to the QueryHandler itself --- .../iguana/cc/query/handler/QueryHandler.java | 81 ++++++++++++++++--- .../iguana/cc/suite/IguanaSuiteParser.java | 44 ++-------- 2 files changed, 76 insertions(+), 49 deletions(-) diff --git a/src/main/java/org/aksw/iguana/cc/query/handler/QueryHandler.java b/src/main/java/org/aksw/iguana/cc/query/handler/QueryHandler.java index fb94fe84..6ddfea35 100644 --- a/src/main/java/org/aksw/iguana/cc/query/handler/QueryHandler.java +++ b/src/main/java/org/aksw/iguana/cc/query/handler/QueryHandler.java @@ -1,6 +1,12 @@ package org.aksw.iguana.cc.query.handler; import com.fasterxml.jackson.annotation.*; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import org.aksw.iguana.cc.query.selector.QuerySelector; import org.aksw.iguana.cc.query.selector.impl.LinearQuerySelector; import org.aksw.iguana.cc.query.selector.impl.RandomQuerySelector; @@ -16,6 +22,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; +import java.util.HashMap; import java.util.Objects; /** @@ -26,37 +33,88 @@ * * @author frensing */ +@JsonDeserialize(using = QueryHandler.Deserializer.class) public class QueryHandler { + static class Deserializer extends StdDeserializer { + final HashMap queryHandlers = new HashMap<>(); + protected Deserializer(Class vc) { + super(vc); + } - public record Config(String path, - Format format, - Boolean caching, - Order order, - Long seed, - Language lang - ) { + protected Deserializer() { + this(null); + } + + @Override + public QueryHandler deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + QueryHandler.Config queryHandlerConfig = ctxt.readValue(jp, QueryHandler.Config.class); + if (!queryHandlers.containsKey(queryHandlerConfig)) + queryHandlers.put(queryHandlerConfig, new QueryHandler(queryHandlerConfig)); + + return queryHandlers.get(queryHandlerConfig); + } + } + public record Config( + String path, + Format format, + Boolean caching, + Order order, + Long seed, + Language lang + ) { public Config(@JsonProperty(required = true) String path, Format format, Boolean caching, Order order, Long seed, Language lang) { this.path = path; this.format = format == null ? Format.ONE_PER_LINE : format; - this.caching = caching == null ? true : caching; + this.caching = caching == null || caching; this.order = order == null ? Order.LINEAR : order; this.seed = seed; this.lang = lang == null ? Language.SPARQL : lang; } + @JsonDeserialize(using = Format.Deserializer.class) public enum Format { @JsonEnumDefaultValue ONE_PER_LINE("one-per-line"), SEPARATOR("separator"), FOLDER("folder"); + static class Deserializer extends StdDeserializer { + protected Deserializer(Class vc) { + super(vc); + } + + protected Deserializer() { + this(null); + } + + @Override + public Format deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { + JsonNode root = deserializationContext.readTree(jsonParser); + if (root.has("separator")) { + Format format = Format.SEPARATOR; + format.setSeparator(root.get("separator").textValue()); + return format; + } else { + return Format.valueOf(root.textValue()); + } + } + } + final String value; + String separator; - @JsonCreator Format(String value) { this.value = Objects.requireNonNullElse(value, "one-per-line"); } + public void setSeparator(String separator) { + this.separator = separator; + } + + public String getSeparator() { + return this.separator; + } + @JsonValue public String value() { return value; @@ -81,8 +139,7 @@ public String value() { public enum Language { @JsonEnumDefaultValue SPARQL("SPARQL"), - UNSPECIFIED("unspecified"), - ; + UNSPECIFIED("unspecified"); final String value; @@ -112,7 +169,7 @@ public String value() { public QueryHandler(Config config) throws IOException { final var querySource = switch (config.format()) { case ONE_PER_LINE -> new FileLineQuerySource(Path.of(config.path())); - case SEPARATOR -> new FileSeparatorQuerySource(Path.of(config.path())); + case SEPARATOR -> new FileSeparatorQuerySource(Path.of(config.path()), config.format.separator); case FOLDER -> new FolderQuerySource(Path.of(config.path())); }; diff --git a/src/main/java/org/aksw/iguana/cc/suite/IguanaSuiteParser.java b/src/main/java/org/aksw/iguana/cc/suite/IguanaSuiteParser.java index 30dc4fd7..e48a792c 100644 --- a/src/main/java/org/aksw/iguana/cc/suite/IguanaSuiteParser.java +++ b/src/main/java/org/aksw/iguana/cc/suite/IguanaSuiteParser.java @@ -10,7 +10,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.networknt.schema.JsonSchema; @@ -19,7 +18,6 @@ import com.networknt.schema.ValidationMessage; import org.aksw.iguana.cc.config.elements.ConnectionConfig; import org.aksw.iguana.cc.config.elements.DatasetConfig; -import org.aksw.iguana.cc.query.handler.QueryHandler; import org.apache.commons.io.FilenameUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,10 +27,7 @@ import java.nio.file.Path; import java.text.MessageFormat; import java.time.Duration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -41,6 +36,8 @@ */ public class IguanaSuiteParser { + record SuiteConfigWithID(long id, Suite.Config config) {} + private static final Logger LOGGER = LoggerFactory.getLogger(IguanaSuiteParser.class); private static final String schemaFile = "iguana-schema.json"; @@ -64,7 +61,7 @@ public static DataFormat getFormat(Path file) { public static Suite parse(Path config) throws IOException { - return parse(new FileInputStream(config.toFile()), DataFormat.getFormat(config), true); + return parse(new FileInputStream(config.toFile()), DataFormat.getFormat(config), true); // TODO: validate } public static Suite parse(InputStream stream, DataFormat format) throws IOException { @@ -81,8 +78,6 @@ public static Suite parse(InputStream inputStream, DataFormat format, Boolean va return new Suite(configWithID.id(), configWithID.config()); } - record SuiteConfigWithID(long id, Suite.Config config) { - } /** * Parses a IGUANA configuration file. @@ -143,7 +138,7 @@ protected ConnectionDeserializer(Class vc) { } @Override - public ConnectionConfig deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + public ConnectionConfig deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { JsonNode node = jp.getCodec().readTree(jp); if (node.isTextual()) { final var connectionName = node.asText(); @@ -160,28 +155,6 @@ public ConnectionConfig deserialize(JsonParser jp, DeserializationContext ctxt) } } - final var queryHandlers = new HashMap(); - - class QueryHandlerDeserializer extends StdDeserializer { - - public QueryHandlerDeserializer() { - this(null); - } - - protected QueryHandlerDeserializer(Class vc) { - super(vc); - } - - @Override - public QueryHandler deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { - QueryHandler.Config queryHandlerConfig = ctxt.readValue(jp, QueryHandler.Config.class); - if (!queryHandlers.containsKey(queryHandlerConfig)) - queryHandlers.put(queryHandlerConfig, new QueryHandler(queryHandlerConfig)); - - return queryHandlers.get(queryHandlerConfig); - } - } - class HumanReadableDurationDeserializer extends StdDeserializer { public HumanReadableDurationDeserializer() { @@ -193,7 +166,7 @@ protected HumanReadableDurationDeserializer(Class vc) { } @Override - public Duration deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + public Duration deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { var durationString = jp.getValueAsString() .replaceAll("\\s+", "") .replace("years", "y") @@ -216,12 +189,10 @@ public Duration deserialize(JsonParser jp, DeserializationContext ctxt) throws I } } - mapper = new ObjectMapper(factory).registerModule(new JavaTimeModule()) .registerModule(new SimpleModule() .addDeserializer(DatasetConfig.class, new DatasetDeserializer()) .addDeserializer(ConnectionConfig.class, new ConnectionDeserializer()) - .addDeserializer(QueryHandler.class, new QueryHandlerDeserializer()) .addDeserializer(Duration.class, new HumanReadableDurationDeserializer())); // TODO: update validator and reactivate // if(validate && !validateConfig(config, schemaFile, mapper)){ @@ -250,8 +221,7 @@ record PreparsingDatasets(@JsonProperty(required = true) List dat private static Map preparseConnections(ObjectMapper mapper, String input) throws JsonProcessingException { @JsonIgnoreProperties(ignoreUnknown = true) - record PreparsingConnections(@JsonProperty(required = true) List connections) { - } + record PreparsingConnections(@JsonProperty(required = true) List connections) {} final var preparsingConnections = mapper.readValue(input, PreparsingConnections.class); return preparsingConnections.connections().stream().collect(Collectors.toMap(ConnectionConfig::name, Function.identity()));