Skip to content

Commit

Permalink
adjust structure of InteractionDescription
Browse files Browse the repository at this point in the history
- move form member
- adjust namings
- remove TD-dependencies
  • Loading branch information
florence committed Jun 2, 2023
1 parent 0081040 commit 8e89853
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 104 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ch.unisg.ics.interactions.wot.td.interaction;

import ch.unisg.ics.interactions.wot.td.affordances.Form;
import lombok.Builder;
import lombok.Getter;
import lombok.NonNull;
Expand Down Expand Up @@ -35,11 +36,18 @@ public class InteractionDescription {
*/
private final InteractionTypes type;

protected InteractionDescription(@NonNull String title, String uri, InteractionInput input, InteractionOutput output, InteractionTypes type) {

/**
* The form of the interaction.
*/
private final Form form;

protected InteractionDescription(@NonNull String title, String uri, InteractionInput input, InteractionOutput output, InteractionTypes type, Form form) {
this.title = title;
this.uri = uri;
this.input = input;
this.output = output;
this.type = type;
this.form = form;
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
package ch.unisg.ics.interactions.wot.td.interaction;

import ch.unisg.ics.interactions.wot.td.affordances.Form;
import ch.unisg.ics.interactions.wot.td.schemas.DataSchema;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public class InteractionInput {

public InteractionInput(Form form) {
this.form = form;
this.value = null;
this.schema = null;
}
private final Object value;
private final Form form;
private final DataSchema schema;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import ch.unisg.ics.interactions.wot.td.interaction.InteractionDescription;
import ch.unisg.ics.interactions.wot.td.interaction.InteractionTypes;
import ch.unisg.ics.interactions.wot.td.schemas.DataSchema;
import ch.unisg.ics.interactions.wot.td.vocabularies.TD;
import org.eclipse.rdf4j.model.BNode;
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.Resource;
Expand All @@ -24,7 +23,6 @@
*/
public class IDGraphWriter {
private static final String[] HTTP_URI_SCHEMES = new String[]{"http:", "https:"};
private final static String tdNS = TD.PREFIX;
private final static String hctlNS = "https://www.w3.org/2019/wot/hypermedia#";
private final static String htvNS = "http://www.w3.org/2011/http#";
private final static String logNS = "https://example.org/log#";
Expand All @@ -45,7 +43,6 @@ public IDGraphWriter(InteractionDescription intd) {
this.graphBuilder = new ModelBuilder();

// Default namespace bindings
graphBuilder.setNamespace("td", tdNS);
graphBuilder.setNamespace("hctl", hctlNS);
graphBuilder.setNamespace("htv", htvNS);
graphBuilder.setNamespace("log", logNS);
Expand All @@ -67,6 +64,7 @@ public String write() {
.addInput()
.addOutput()
.addType()
.addForm()
.write(RDFFormat.TURTLE);
}

Expand All @@ -87,13 +85,13 @@ public IDGraphWriter setNamespace(String prefix, String namespace) {
}

private IDGraphWriter addTitle() {
graphBuilder.add(intdId, rdf.createIRI(TD.title), intd.getTitle());
graphBuilder.add(intdId, rdf.createIRI(logNS, "title"), intd.getTitle());
return this;
}

private IDGraphWriter addURI() {
if (intd.getUri() != null && !intd.getUri().isEmpty()) {
graphBuilder.add(intdId, rdf.createIRI(TD.hasBase), rdf.createIRI(intd.getUri()));
graphBuilder.add(intdId, rdf.createIRI(logNS, "uri"), rdf.createIRI(intd.getUri()));
}

return this;
Expand All @@ -117,15 +115,13 @@ private IDGraphWriter addInput() {
}

BNode inputId = rdf.createBNode();
graphBuilder.add(intdId, rdf.createIRI(tdNS, "hasInput"), inputId);
graphBuilder.add(intdId, rdf.createIRI(logNS, "hasInput"), inputId);

// Not all requests have a request body with a data schema
if(intd.getInput().getValue() != null) {
graphBuilder.add(inputId, rdf.createIRI(tdNS, "value"), intd.getInput().getValue());
graphBuilder.add(inputId, rdf.createIRI(logNS, "value"), intd.getInput().getValue());
addSchema(inputId, intd.getInput().getSchema());
}

addFormForInput(inputId, intd.getInput().getForm());
return this;
}

Expand All @@ -139,8 +135,8 @@ private IDGraphWriter addOutput() {
}

Resource outputId = rdf.createBNode();
graphBuilder.add(intdId, rdf.createIRI(tdNS, "hasOutput"), outputId);
graphBuilder.add(outputId, rdf.createIRI(tdNS, "value"), intd.getOutput().getValue());
graphBuilder.add(intdId, rdf.createIRI(logNS, "hasOutput"), outputId);
graphBuilder.add(outputId, rdf.createIRI(logNS, "value"), intd.getOutput().getValue());
addSchema(outputId, intd.getOutput().getSchema());
return this;
}
Expand All @@ -150,20 +146,28 @@ private void addSchema(Resource nodeId, DataSchema schema) {
}

/**
* @param inputId the id of the input node
* @param form form of the interaction (e.g. HTTP GET Request)
*
*/
private void addFormForInput(BNode inputId, Form form) {
private IDGraphWriter addForm() {
// Not all requests have a form
if(intd.getForm() == null) {
return this;
}

BNode formId = rdf.createBNode();
graphBuilder.add(inputId, rdf.createIRI(TD.hasForm), formId);
graphBuilder.add(intdId, rdf.createIRI(logNS, "hasForm"), formId);

Form form = intd.getForm();

// Only writes the method name for forms with one operation type (to avoid ambiguity)
if (form.getMethodName().isPresent() && form.getOperationTypes().size() == 1) {
if (Arrays.stream(HTTP_URI_SCHEMES).anyMatch(form.getTarget()::contains)) {
graphBuilder.add(formId, rdf.createIRI(htvNS, "methodName"), form.getMethodName().get());
}
}

FormGraphWriter.write(graphBuilder, formId, form);
return this;
}

private Model getModel() {
Expand All @@ -177,11 +181,11 @@ private Model getModel() {
private IDGraphWriter addType() {
if (intd.getType() != null) {
if (intd.getType().equals(InteractionTypes.PROPERTY)) {
graphBuilder.add(intdId, RDF.TYPE, rdf.createIRI(logNS, "PropertyLog"));
graphBuilder.add(intdId, RDF.TYPE, rdf.createIRI(logNS, "PropertyObservation"));
} else if (intd.getType().equals(InteractionTypes.ACTION)) {
graphBuilder.add(intdId, RDF.TYPE, rdf.createIRI(logNS, "ActionLog"));
graphBuilder.add(intdId, RDF.TYPE, rdf.createIRI(logNS, "ActionExecution"));
} else if (intd.getType().equals(InteractionTypes.EVENT)) {
graphBuilder.add(intdId, RDF.TYPE, rdf.createIRI(logNS, "EventLog"));
graphBuilder.add(intdId, RDF.TYPE, rdf.createIRI(logNS, "Event"));
}
}
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,11 @@ public void testURI() {

@Test
public void testInput() {
Form form = new Form.Builder("http://example.org/action")
.addOperationType(TD.invokeAction)
.setContentType("application/json")
.setMethodName("POST")
.build();

DataSchema schema = new DataSchema.Builder()
.addSemanticType(DataSchema.STRING)
.build();

InteractionInput input = new InteractionInput("input1", form, schema);
InteractionInput input = new InteractionInput("input1", schema);

InteractionDescription intd = InteractionDescription.builder()
.title("interaction-1")
Expand All @@ -75,6 +69,22 @@ public void testOutput() {
assertSame(output, intd.getOutput());
}

@Test
public void testForm() {
Form form = new Form.Builder("http://example.org/action")
.addOperationType(TD.invokeAction)
.setContentType("application/json")
.setMethodName("POST")
.build();

InteractionDescription intd = InteractionDescription.builder()
.title("interaction-1")
.form(form)
.build();

assertEquals(form, intd.getForm());
}

@Test
public void testTypeAction() {
InteractionDescription intd = InteractionDescription.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@
import static org.junit.Assert.assertTrue;

public class IDGraphWriterTest {
private static final String ID_TITLE = "interaction-1";
private static final String ID_TITLE = "actionlog-1";
private static final String PREFIXES =
"@prefix td: <https://www.w3.org/2019/wot/td#> .\n" +
"@prefix hctl: <https://www.w3.org/2019/wot/hypermedia#> .\n" +
"@prefix htv: <http://www.w3.org/2011/http#> .\n" +
"@prefix log: <https://example.org/log#> .\n";
Expand Down Expand Up @@ -56,29 +55,30 @@ public void init() {
public void testWriteCompleteID() throws IOException {
InteractionDescription completeIntD = InteractionDescription.builder()
.title(ID_TITLE)
.input(new InteractionInput("input1", POST_FORM, STRING_SCHEMA))
.uri("http://example.org/log#actionlog-1")
.form(POST_FORM)
.input(new InteractionInput("input1", STRING_SCHEMA))
.output(new InteractionOutput("output1", STRING_SCHEMA))
.type(InteractionTypes.ACTION)
.uri("http://example.org/log#interaction-1")
.build();

String testID = PREFIXES + String.format(
"\n<http://example.org/log#interaction-1> a log:ActionLog;\n" +
" td:title \"interaction-1\";\n" +
" td:hasBase <http://example.org/log#interaction-1>;\n" +
" log:created \"%s\";\n" +
" td:hasInput [ a <https://www.w3.org/2019/wot/json-schema#StringSchema>;\n" +
" td:value \"input1\";\n" +
" td:hasForm [\n" +
" htv:methodName \"POST\";\n" +
" hctl:hasTarget <http://example.org/action>;\n" +
" hctl:forContentType \"application/json\";\n" +
" hctl:hasOperationType td:invokeAction\n" +
" ]\n" +
" ];\n" +
" td:hasOutput [ a <https://www.w3.org/2019/wot/json-schema#StringSchema>;\n" +
" td:value \"output1\"\n" +
" ] .\n", getDateTimeWithoutSeconds());
"\n<http://example.org/log#actionlog-1> a log:ActionExecution;\n" +
" log:title \"actionlog-1\";\n" +
" log:uri <http://example.org/log#actionlog-1>;\n" +
" log:created \"%s\";\n" +
" log:hasInput [ a <https://www.w3.org/2019/wot/json-schema#StringSchema>;\n" +
" log:value \"input1\"\n" +
" ];\n" +
" log:hasOutput [ a <https://www.w3.org/2019/wot/json-schema#StringSchema>;\n" +
" log:value \"output1\"\n" +
" ];\n" +
" log:hasForm [\n" +
" htv:methodName \"POST\";\n" +
" hctl:hasTarget <http://example.org/action>;\n" +
" hctl:forContentType \"application/json\";\n" +
" hctl:hasOperationType <https://www.w3.org/2019/wot/td#invokeAction>\n" +
" ] .\n", getDateTimeWithoutSeconds());

assertIsomorphicGraphs(testID, completeIntD);
}
Expand All @@ -88,75 +88,53 @@ public void testWriteIDWithoutInput() throws IOException {
InteractionDescription intDWithoutInput = InteractionDescription.builder()
.title(ID_TITLE)
.type(InteractionTypes.EVENT)
.form(GET_FORM)
.output(new InteractionOutput("output1", STRING_SCHEMA))
.uri("http://example.org/log#interaction-1")
.uri("http://example.org/log#actionlog-1")
.build();

String testID = PREFIXES + String.format(
"\n<http://example.org/log#interaction-1> a log:EventLog;\n" +
" td:title \"interaction-1\";\n" +
" td:hasBase <http://example.org/log#interaction-1>;\n" +
"\n<http://example.org/log#actionlog-1> a log:Event;\n" +
" log:title \"actionlog-1\";\n" +
" log:uri <http://example.org/log#actionlog-1>;\n" +
" log:created \"%s\";\n" +
" td:hasOutput [ a <https://www.w3.org/2019/wot/json-schema#StringSchema>;\n" +
" td:value \"output1\"\n" +
" ] .\n", getDateTimeWithoutSeconds());

assertIsomorphicGraphs(testID, intDWithoutInput);
}

@Test
public void testWriteIDWithoutInputValue() throws IOException {
InteractionDescription requestIntD = InteractionDescription.builder()
.title(ID_TITLE)
.input(new InteractionInput(GET_FORM))
.output(new InteractionOutput("output1", STRING_SCHEMA))
.type(InteractionTypes.ACTION)
.uri("http://example.org/log#interaction-1")
.build();

String testID = PREFIXES + String.format(
"\n<http://example.org/log#interaction-1> a log:ActionLog;\n" +
" td:title \"interaction-1\";\n" +
" td:hasBase <http://example.org/log#interaction-1>;\n" +
" log:created \"%s\";\n" +
" td:hasInput [\n" +
" td:hasForm [\n" +
" htv:methodName \"GET\";\n" +
" hctl:hasTarget <http://example.org/action>;\n" +
" hctl:forContentType \"application/json\";\n" +
" hctl:hasOperationType td:readProperty\n" +
" ]\n" +
" log:hasOutput [ a <https://www.w3.org/2019/wot/json-schema#StringSchema>;\n" +
" log:value \"output1\"\n" +
" ];\n" +
" td:hasOutput [ a <https://www.w3.org/2019/wot/json-schema#StringSchema>;\n" +
" td:value \"output1\"\n" +
" ] .\n", getDateTimeWithoutSeconds());
" log:hasForm [\n" +
" htv:methodName \"GET\";\n" +
" hctl:hasTarget <http://example.org/action>;\n" +
" hctl:forContentType \"application/json\";\n" +
" hctl:hasOperationType <https://www.w3.org/2019/wot/td#readProperty>\n" +
" ] .", getDateTimeWithoutSeconds());

assertIsomorphicGraphs(testID, requestIntD);
assertIsomorphicGraphs(testID, intDWithoutInput);
}

@Test
public void testWriteIDWithoutOutput() throws IOException {
InteractionDescription intDWithoutOutput = InteractionDescription.builder()
.title(ID_TITLE)
.input(new InteractionInput("input1", POST_FORM, STRING_SCHEMA))
.input(new InteractionInput("input1", STRING_SCHEMA))
.form(POST_FORM)
.type(InteractionTypes.ACTION)
.uri("http://example.org/log#interaction-1")
.build();

String testID = PREFIXES + String.format(
"\n<http://example.org/log#interaction-1> a log:ActionLog;\n" +
" td:title \"interaction-1\";\n" +
" td:hasBase <http://example.org/log#interaction-1>;\n" +
"\n<http://example.org/log#interaction-1> a log:ActionExecution;\n" +
" log:title \"actionlog-1\";\n" +
" log:uri <http://example.org/log#interaction-1>;\n" +
" log:created \"%s\";\n" +
" td:hasInput [ a <https://www.w3.org/2019/wot/json-schema#StringSchema>;\n" +
" td:value \"input1\";\n" +
" td:hasForm [\n" +
" htv:methodName \"POST\";\n" +
" hctl:hasTarget <http://example.org/action>;\n" +
" hctl:forContentType \"application/json\";\n" +
" hctl:hasOperationType td:invokeAction\n" +
" ]\n" +
" ].\n", getDateTimeWithoutSeconds());
" log:hasInput [ a <https://www.w3.org/2019/wot/json-schema#StringSchema>;\n" +
" log:value \"input1\"\n" +
" ];\n" +
" log:hasForm [\n" +
" htv:methodName \"POST\";\n" +
" hctl:hasTarget <http://example.org/action>;\n" +
" hctl:forContentType \"application/json\";\n" +
" hctl:hasOperationType <https://www.w3.org/2019/wot/td#invokeAction>\n" +
" ] .", getDateTimeWithoutSeconds());

assertIsomorphicGraphs(testID, intDWithoutOutput);
}
Expand Down

0 comments on commit 8e89853

Please sign in to comment.