From c98baf8fe3524ac1a61c79ce7e2b5a9e312566fc Mon Sep 17 00:00:00 2001 From: florence Date: Mon, 5 Jun 2023 17:35:48 +0200 Subject: [PATCH] refactor interaction input and output - add json-schema namespace - add tests for different input and output types - change namings --- .../interactions/wot/td/io/IDGraphWriter.java | 26 ++- .../wot/td/io/IDGraphWriterTest.java | 216 ++++++++++++++++-- 2 files changed, 220 insertions(+), 22 deletions(-) diff --git a/src/main/java/ch/unisg/ics/interactions/wot/td/io/IDGraphWriter.java b/src/main/java/ch/unisg/ics/interactions/wot/td/io/IDGraphWriter.java index 271fd15..f64e102 100644 --- a/src/main/java/ch/unisg/ics/interactions/wot/td/io/IDGraphWriter.java +++ b/src/main/java/ch/unisg/ics/interactions/wot/td/io/IDGraphWriter.java @@ -27,6 +27,8 @@ public class IDGraphWriter { private final static String htvNS = "http://www.w3.org/2011/http#"; private final static String logNS = "https://example.org/log#"; + private final static String jsNS = "https://www.w3.org/2019/wot/json-schema#"; + private final Resource intdId; private final InteractionDescription intd; private final ModelBuilder graphBuilder; @@ -46,6 +48,7 @@ public IDGraphWriter(InteractionDescription intd) { graphBuilder.setNamespace("hctl", hctlNS); graphBuilder.setNamespace("htv", htvNS); graphBuilder.setNamespace("log", logNS); + graphBuilder.setNamespace("js", jsNS); } /** @@ -119,9 +122,11 @@ private IDGraphWriter addInput() { // Not all requests have a request body with a data schema if(intd.getInput().getValue() != null) { - graphBuilder.add(inputId, rdf.createIRI(logNS, "value"), intd.getInput().getValue()); + addValue(inputId, intd.getInput().getValue()); addSchema(inputId, intd.getInput().getSchema()); } + + graphBuilder.add(inputId, RDF.TYPE, rdf.createIRI(logNS, "Input")); return this; } @@ -134,15 +139,26 @@ private IDGraphWriter addOutput() { return this; } - Resource outputId = rdf.createBNode(); + BNode outputId = rdf.createBNode(); graphBuilder.add(intdId, rdf.createIRI(logNS, "hasOutput"), outputId); - graphBuilder.add(outputId, rdf.createIRI(logNS, "value"), intd.getOutput().getValue()); - addSchema(outputId, intd.getOutput().getSchema()); + + // Not all interactions have a response body with a data schema + if(intd.getOutput().getValue() != null) { + addValue(outputId, intd.getOutput().getValue()); + addSchema(outputId, intd.getOutput().getSchema()); + } + + graphBuilder.add(outputId, RDF.TYPE, rdf.createIRI(logNS, "Output")); return this; } + private void addValue(BNode nodeId, Object value) { + graphBuilder.add(nodeId, rdf.createIRI(logNS, "hasValue"), value); + } private void addSchema(Resource nodeId, DataSchema schema) { - SchemaGraphWriter.write(graphBuilder, nodeId, schema); + BNode schemaId = rdf.createBNode(); + graphBuilder.add(nodeId, rdf.createIRI(logNS, "hasSchema"), schemaId); + SchemaGraphWriter.write(graphBuilder, schemaId, schema); } /** diff --git a/src/test/java/ch/unisg/ics/interactions/wot/td/io/IDGraphWriterTest.java b/src/test/java/ch/unisg/ics/interactions/wot/td/io/IDGraphWriterTest.java index 7565d15..4132fdd 100644 --- a/src/test/java/ch/unisg/ics/interactions/wot/td/io/IDGraphWriterTest.java +++ b/src/test/java/ch/unisg/ics/interactions/wot/td/io/IDGraphWriterTest.java @@ -7,6 +7,9 @@ import ch.unisg.ics.interactions.wot.td.affordances.Form; import ch.unisg.ics.interactions.wot.td.schemas.*; import ch.unisg.ics.interactions.wot.td.vocabularies.TD; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; import org.eclipse.rdf4j.model.Model; import org.eclipse.rdf4j.model.util.Models; import org.eclipse.rdf4j.rio.RDFFormat; @@ -26,13 +29,16 @@ public class IDGraphWriterTest { private static final String PREFIXES = "@prefix hctl: .\n" + "@prefix htv: .\n" + - "@prefix log: .\n"; + "@prefix log: .\n" + + "@prefix js: .\n"; private Form GET_FORM; private Form POST_FORM; private StringSchema STRING_SCHEMA; - + private IntegerSchema INTEGER_SCHEMA; + private ArraySchema ARRAY_SCHEMA; + private ObjectSchema OBJECT_SCHEMA; private static final String IO_BASE_IRI = "http://example.org/"; @Before @@ -49,6 +55,9 @@ public void init() { .build(); this.STRING_SCHEMA = new StringSchema.Builder().build(); + this.INTEGER_SCHEMA = new IntegerSchema.Builder().build(); + this.ARRAY_SCHEMA = new ArraySchema.Builder().build(); + this.OBJECT_SCHEMA = new ObjectSchema.Builder().build(); } @Test @@ -67,11 +76,15 @@ public void testWriteCompleteID() throws IOException { " log:title \"actionlog-1\";\n" + " log:uri ;\n" + " log:created \"%s\";\n" + - " log:hasInput [ a ;\n" + - " log:value \"input1\"\n" + + " log:hasInput [ a log:Input;\n" + + " log:hasValue \"input1\";\n" + + " log:hasSchema [ a js:StringSchema\n" + + " ]\n" + " ];\n" + - " log:hasOutput [ a ;\n" + - " log:value \"output1\"\n" + + " log:hasOutput [ a log:Output;\n" + + " log:hasValue \"output1\";\n" + + " log:hasSchema [ a js:StringSchema\n" + + " ]\n" + " ];\n" + " log:hasForm [\n" + " htv:methodName \"POST\";\n" + @@ -84,8 +97,8 @@ public void testWriteCompleteID() throws IOException { } @Test - public void testWriteIDWithoutInput() throws IOException { - InteractionDescription intDWithoutInput = InteractionDescription.builder() + public void testWriteIDWithStringOutput() throws IOException { + InteractionDescription intDWithStringOutput = InteractionDescription.builder() .title(ID_TITLE) .type(InteractionTypes.EVENT) .form(GET_FORM) @@ -98,8 +111,10 @@ public void testWriteIDWithoutInput() throws IOException { " log:title \"actionlog-1\";\n" + " log:uri ;\n" + " log:created \"%s\";\n" + - " log:hasOutput [ a ;\n" + - " log:value \"output1\"\n" + + " log:hasOutput [ a log:Output;\n" + + " log:hasValue \"output1\";\n" + + " log:hasSchema [ a js:StringSchema\n" + + " ]\n" + " ];\n" + " log:hasForm [\n" + " htv:methodName \"GET\";\n" + @@ -108,12 +123,12 @@ public void testWriteIDWithoutInput() throws IOException { " hctl:hasOperationType \n" + " ] .", getDateTimeWithoutSeconds()); - assertIsomorphicGraphs(testID, intDWithoutInput); + assertIsomorphicGraphs(testID, intDWithStringOutput); } @Test - public void testWriteIDWithoutOutput() throws IOException { - InteractionDescription intDWithoutOutput = InteractionDescription.builder() + public void testWriteIDWithStringInput() throws IOException { + InteractionDescription intDWithStringInput = InteractionDescription.builder() .title(ID_TITLE) .input(new InteractionInput("input1", STRING_SCHEMA)) .form(POST_FORM) @@ -126,19 +141,186 @@ public void testWriteIDWithoutOutput() throws IOException { " log:title \"actionlog-1\";\n" + " log:uri ;\n" + " log:created \"%s\";\n" + - " log:hasInput [ a ;\n" + - " log:value \"input1\"\n" + + " log:hasInput [ a log:Input;\n" + + " log:hasValue \"input1\";\n" + + " log:hasSchema [ a js:StringSchema\n" + + " ]\n" + " ];\n" + " log:hasForm [\n" + " htv:methodName \"POST\";\n" + " hctl:hasTarget ;\n" + " hctl:forContentType \"application/json\";\n" + " hctl:hasOperationType \n" + - " ] .", getDateTimeWithoutSeconds()); + " ] .\n", getDateTimeWithoutSeconds()); + + assertIsomorphicGraphs(testID, intDWithStringInput); + } + + @Test + public void testWriteIDWithIntegerInput() throws IOException { + InteractionDescription intDWithIntegerInput = InteractionDescription.builder() + .title(ID_TITLE) + .input(new InteractionInput(1, INTEGER_SCHEMA)) + .uri("http://example.org/log#interaction-1") + .build(); + + String testID = PREFIXES + String.format( + "\n log:title \"actionlog-1\";\n" + + " log:uri ;\n" + + " log:created \"%s\";\n" + + " log:hasInput [ a log:Input;\n" + + " log:hasValue \"1\"^^xsd:int;\n" + + " log:hasSchema [ a js:IntegerSchema\n" + + " ]\n" + + " ] .\n", getDateTimeWithoutSeconds()); + + assertIsomorphicGraphs(testID, intDWithIntegerInput); + } + + @Test + public void testWriteIDWithIntegerOutput() throws IOException { + InteractionDescription intDWithIntegerOutput = InteractionDescription.builder() + .title(ID_TITLE) + .output(new InteractionOutput(1, INTEGER_SCHEMA)) + .uri("http://example.org/log#interaction-1") + .build(); + + String testID = PREFIXES + String.format( + "\n log:title \"actionlog-1\";\n" + + " log:uri ;\n" + + " log:created \"%s\";\n" + + " log:hasOutput [ a log:Output;\n" + + " log:hasValue \"1\"^^xsd:int;\n" + + " log:hasSchema [ a js:IntegerSchema\n" + + " ]\n" + + " ] .\n", getDateTimeWithoutSeconds()); + + assertIsomorphicGraphs(testID, intDWithIntegerOutput); + } + + @Test + public void testWriteIDWithObjectInput() throws IOException { + JsonObject body = new JsonObject(); + body.addProperty("currentTemperature", 3.0); + body.addProperty("isActive", true); + body.add("pastValues", new Gson().toJsonTree(new Integer[]{1, 2, 3})); + + InteractionDescription intDWithObjectInput = InteractionDescription.builder() + .title(ID_TITLE) + .input(new InteractionInput(body, OBJECT_SCHEMA)) + .uri("http://example.org/log#interaction-1") + .build(); + + String testID = PREFIXES + String.format( + "\n log:title \"actionlog-1\";\n" + + " log:uri ;\n" + + " log:created \"%s\";\n" + + " log:hasInput [ a log:Input;\n" + + " log:hasValue \"{\\\"currentTemperature\\\":3.0,\\\"isActive\\\":true,\\\"pastValues\\\":[1,2,3]}\";\n" + + " log:hasSchema [ a js:ObjectSchema\n" + + " ]\n" + + " ] .\n", getDateTimeWithoutSeconds()); + + assertIsomorphicGraphs(testID, intDWithObjectInput); + } + + @Test + public void testWriteIDWithObjectOutput() throws IOException { + JsonObject body = new JsonObject(); + body.addProperty("currentTemperature", 3.0); + body.addProperty("isActive", true); + body.add("pastValues", new Gson().toJsonTree(new Integer[]{1, 2, 3})); + + InteractionDescription intDWithObjectInput = InteractionDescription.builder() + .title(ID_TITLE) + .output(new InteractionOutput(body, OBJECT_SCHEMA)) + .uri("http://example.org/log#interaction-1") + .build(); + + String testID = PREFIXES + String.format( + "\n log:title \"actionlog-1\";\n" + + " log:uri ;\n" + + " log:created \"%s\";\n" + + " log:hasOutput [ a log:Output;\n" + + " log:hasValue \"{\\\"currentTemperature\\\":3.0,\\\"isActive\\\":true,\\\"pastValues\\\":[1,2,3]}\";\n" + + " log:hasSchema [ a js:ObjectSchema\n" + + " ]\n" + + " ] .\n", getDateTimeWithoutSeconds()); + + assertIsomorphicGraphs(testID, intDWithObjectInput); + } + + @Test + public void testWriteIDWithArrayInput() throws IOException { + JsonArray body = new JsonArray(); + body.add("input1"); + body.add("input2"); + body.add("input3"); + + InteractionDescription intDWithArrayInput = InteractionDescription.builder() + .title(ID_TITLE) + .uri("http://example.org/log#actionlog-1") + .form(POST_FORM) + .input(new InteractionInput(body, ARRAY_SCHEMA)) + .type(InteractionTypes.ACTION) + .build(); + + String testID = PREFIXES + String.format( + "\n a log:ActionExecution;\n" + + " log:title \"actionlog-1\";\n" + + " log:uri ;\n" + + " log:created \"%s\";\n" + + " log:hasInput [ a log:Input;\n" + + " log:hasValue \"[\\\"input1\\\",\\\"input2\\\",\\\"input3\\\"]\";\n" + + " log:hasSchema [ a js:ArraySchema\n" + + " ]\n" + + " ];\n" + + " log:hasForm [\n" + + " htv:methodName \"POST\";\n" + + " hctl:hasTarget ;\n" + + " hctl:forContentType \"application/json\";\n" + + " hctl:hasOperationType \n" + + " ] .\n", getDateTimeWithoutSeconds()); - assertIsomorphicGraphs(testID, intDWithoutOutput); + assertIsomorphicGraphs(testID, intDWithArrayInput); } + @Test + public void testWriteIDWithArrayOutput() throws IOException { + JsonArray body = new JsonArray(); + body.add("output1"); + body.add("output2"); + body.add("output3"); + + InteractionDescription intDWithArrayOutput = InteractionDescription.builder() + .title(ID_TITLE) + .uri("http://example.org/log#actionlog-1") + .form(POST_FORM) + .output(new InteractionOutput(body, ARRAY_SCHEMA)) + .type(InteractionTypes.ACTION) + .build(); + + String testID = PREFIXES + String.format( + "\n a log:ActionExecution;\n" + + " log:title \"actionlog-1\";\n" + + " log:uri ;\n" + + " log:created \"%s\";\n" + + " log:hasOutput [ a log:Output;\n" + + " log:hasValue \"[\\\"output1\\\",\\\"output2\\\",\\\"output3\\\"]\";\n" + + " log:hasSchema [ a js:ArraySchema\n" + + " ]\n" + + " ];\n" + + " log:hasForm [\n" + + " htv:methodName \"POST\";\n" + + " hctl:hasTarget ;\n" + + " hctl:forContentType \"application/json\";\n" + + " hctl:hasOperationType \n" + + " ] .\n", getDateTimeWithoutSeconds()); + + assertIsomorphicGraphs(testID, intDWithArrayOutput); + } + + private String getDateTimeWithoutSeconds() { OffsetDateTime dateTime = OffsetDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm");