diff --git a/.gitignore b/.gitignore
index bf721ea6..3f08db50 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@ bin/
.DS_Store
.classpath
.project
+.idea
# Ignore Gradle GUI config
gradle-app.setting
diff --git a/build.gradle b/build.gradle
index 4d1c9c43..d656ec4d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ apply plugin: 'maven-publish'
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
-
+
withJavadocJar()
withSourcesJar()
}
@@ -20,6 +20,7 @@ dependencies {
implementation 'org.apache.httpcomponents.client5:httpclient5:5.1'
implementation 'org.apache.httpcomponents.client5:httpclient5-fluent:5.1'
implementation 'com.google.code.gson:gson:2.8.8'
+ implementation 'org.glassfish:javax.json:1.1.4'
implementation 'org.eclipse.rdf4j:rdf4j-runtime:3.7.2'
implementation 'org.slf4j:slf4j-api:2.0.0-alpha5'
diff --git a/src/main/java/ch/unisg/ics/interactions/wot/td/ThingDescription.java b/src/main/java/ch/unisg/ics/interactions/wot/td/ThingDescription.java
index cd74363f..2d5377c0 100644
--- a/src/main/java/ch/unisg/ics/interactions/wot/td/ThingDescription.java
+++ b/src/main/java/ch/unisg/ics/interactions/wot/td/ThingDescription.java
@@ -19,41 +19,41 @@
import ch.unisg.ics.interactions.wot.td.security.SecurityScheme;
/**
- * An immutable representation of a W3C Web of
- * Things Thing Description (TD). A ThingDescription is instantiated using a
+ * An immutable representation of a W3C Web of
+ * Things Thing Description (TD). A ThingDescription is instantiated using a
* ThingDescription.Builder.
- *
- * The current version does not yet implement all the core vocabulary terms defined by the
+ *
+ * The current version does not yet implement all the core vocabulary terms defined by the
* W3C Recommendation.
*/
public class ThingDescription {
private final String title;
private final List security;
-
+
private final Optional uri;
private final Set types;
private final Optional baseURI;
-
+
private final List properties;
private final List actions;
-
+
private final Optional graph;
-
+
/**
- * Supported serialization formats -- currently only RDF serialization formats, namely Turtle and
+ * Supported serialization formats -- currently only RDF serialization formats, namely Turtle and
* JSON-LD 1.0. The version of JSON-LD currently supported is the one provided by RDF4J.
*/
public enum TDFormat {
RDF_TURTLE,
RDF_JSONLD
};
-
- protected ThingDescription(String title, List security, Optional uri,
- Set types, Optional baseURI, List properties,
+
+ protected ThingDescription(String title, List security, Optional uri,
+ Set types, Optional baseURI, List properties,
List actions, Optional graph) {
-
+
this.title = title;
-
+
if (security.isEmpty()) {
security.add(new NoSecurityScheme());
}
@@ -62,66 +62,66 @@ protected ThingDescription(String title, List security, Optional
this.uri = uri;
this.types = types;
this.baseURI = baseURI;
-
+
this.properties = properties;
this.actions = actions;
-
+
this.graph = graph;
}
-
+
public String getTitle() {
return title;
}
-
+
public List getSecuritySchemes() {
return security;
}
-
+
/**
* Gets the first {@link SecurityScheme} that matches a given semantic type.
- *
+ *
* @param type the type of the security scheme
* @return an Optional with the security scheme (empty if not found)
*/
public Optional getFirstSecuritySchemeByType(String type) {
return security.stream().filter(security -> security.getSchemeType().equals(type)).findFirst();
}
-
+
public Optional getThingURI() {
return uri;
}
-
+
public Set getSemanticTypes() {
return types;
}
-
+
public Optional getBaseURI() {
return baseURI;
}
-
+
/**
- * Gets a set with all the semantic types of the action affordances provided by the described
+ * Gets a set with all the semantic types of the action affordances provided by the described
* thing.
- *
+ *
* @return The set of semantic types, can be empty.
*/
public Set getSupportedActionTypes() {
Set supportedActionTypes = new HashSet();
-
+
for (ActionAffordance action : actions) {
supportedActionTypes.addAll(action.getSemanticTypes());
}
-
+
return supportedActionTypes;
}
-
+
/**
- * Gets a property affordance by name, which is specified using the td:name data
+ * Gets a property affordance by name, which is specified using the td:name data
* property defined by the TD vocabulary. Names are mandatory in JSON-based representations. If a
- * name is present, it is unique within the scope of a TD.
- *
- * @param name the name of the property affordance
- * @return an Optional with the property affordance (empty if not found)
+ * name is present, it is unique within the scope of a TD.
+ *
+ * @param name the name of the property affordance
+ * @return an Optional with the property affordance (empty if not found)
*/
public Optional getPropertyByName(String name) {
for (PropertyAffordance property : properties) {
@@ -133,14 +133,14 @@ public Optional getPropertyByName(String name) {
return Optional.empty();
}
-
+
/**
- * Gets a list of property affordances that have a {@link ch.unisg.ics.interactions.wot.td.affordances.Form}
+ * Gets a list of property affordances that have a {@link ch.unisg.ics.interactions.wot.td.affordances.Form}
* hypermedia control for the given operation type.
- *
+ *
* The current implementation supports two operation types for properties: td:readProperty
* and td:writeProperty.
- *
+ *
* @param operationType a string that captures the operation type
* @return the list of property affordances
*/
@@ -148,10 +148,10 @@ public List getPropertiesByOperationType(String operationTyp
return properties.stream().filter(property -> property.hasFormWithOperationType(operationType))
.collect(Collectors.toList());
}
-
+
/**
* Gets the first {@link PropertyAffordance} annotated with a given semantic type.
- *
+ *
* @param propertyType the semantic type, typically and IRI defined in some ontology
* @return an Optional with the property affordance (empty if not found)
*/
@@ -161,17 +161,17 @@ public Optional getFirstPropertyBySemanticType(String proper
return Optional.of(property);
}
}
-
+
return Optional.empty();
}
-
+
/**
- * Gets an action affordance by name, which is specified using the td:name data
+ * Gets an action affordance by name, which is specified using the td:name data
* property defined by the TD vocabulary. Names are mandatory in JSON-based representations. If a
- * name is present, it is unique within the scope of a TD.
- *
- * @param name the name of the action affordance
- * @return an Optional with the action affordance (empty if not found)
+ * name is present, it is unique within the scope of a TD.
+ *
+ * @param name the name of the action affordance
+ * @return an Optional with the action affordance (empty if not found)
*/
public Optional getActionByName(String name) {
for (ActionAffordance action : actions) {
@@ -180,17 +180,17 @@ public Optional getActionByName(String name) {
return Optional.of(action);
}
}
-
+
return Optional.empty();
}
-
+
/**
- * Gets a list of action affordances that have a {@link ch.unisg.ics.interactions.wot.td.affordances.Form}
+ * Gets a list of action affordances that have a {@link ch.unisg.ics.interactions.wot.td.affordances.Form}
* hypermedia control for the given operation type.
- *
- * There is one operation type available actions: td:invokeAction. The API will be
+ *
+ * There is one operation type available actions: td:invokeAction. The API will be
* simplified in future iterations.
- *
+ *
* @param operationType a string that captures the operation type
* @return the list of property affordances
*/
@@ -198,10 +198,10 @@ public List getActionsByOperationType(String operationType) {
return actions.stream().filter(action -> action.hasFormWithOperationType(operationType))
.collect(Collectors.toList());
}
-
+
/**
* Gets the first {@link ActionAffordance} annotated with a given semantic type.
- *
+ *
* @param actionType the semantic type, typically and IRI defined in some ontology
* @return an Optional with the action affordance (empty if not found)
*/
@@ -211,126 +211,130 @@ public Optional getFirstActionBySemanticType(String actionType
return Optional.of(action);
}
}
-
+
return Optional.empty();
}
-
+
public List getProperties() {
return this.properties;
}
-
+
public List getActions() {
return this.actions;
}
-
+
public Optional getGraph() {
return graph;
}
-
+
/**
* Helper class used to construct a ThingDescription. All TDs should have a mandatory
- * title field. In addition to the optional fields defined by the W3C Recommendation,
+ * title field. In addition to the optional fields defined by the W3C Recommendation,
* the addGraph method allows to add any other metadata as an RDF graph.
- *
+ *
* Implements a fluent API.
*/
public static class Builder {
private final String title;
private final List security;
-
+
private Optional uri;
private Optional baseURI;
private final Set types;
-
+
private final List properties;
private final List actions;
-
+
private Optional graph;
-
+
public Builder(String title) {
this.title = title;
this.security = new ArrayList();
-
+
this.uri = Optional.empty();
this.baseURI = Optional.empty();
this.types= new HashSet();
-
+
this.properties = new ArrayList();
this.actions = new ArrayList();
-
+
this.graph = Optional.empty();
}
-
+
public Builder addSecurityScheme(SecurityScheme security) {
this.security.add(security);
return this;
}
-
+
public Builder addSecuritySchemes(List security) {
this.security.addAll(security);
return this;
}
-
+
public Builder addThingURI(String uri) {
this.uri = Optional.of(uri);
return this;
}
-
+
public Builder addBaseURI(String baseURI) {
this.baseURI = Optional.of(baseURI);
return this;
}
-
+
public Builder addSemanticType(String type) {
this.types.add(type);
return this;
}
-
+
public Builder addSemanticTypes(Set thingTypes) {
this.types.addAll(thingTypes);
return this;
}
-
+
public Builder addProperty(PropertyAffordance property) {
this.properties.add(property);
return this;
}
-
+
public Builder addProperties(List properties) {
this.properties.addAll(properties);
return this;
}
-
+
public Builder addAction(ActionAffordance action) {
this.actions.add(action);
return this;
}
-
+
public Builder addActions(List actions) {
this.actions.addAll(actions);
return this;
}
-
+
/**
- * Adds an RDF graph. If an RDF graph is already present, it will be merged with the new graph.
- *
+ * Adds an RDF graph. If an RDF graph is already present, it will be merged with the new graph.
+ *
* @param graph the RDF graph to be added
* @return this Builder
*/
public Builder addGraph(Model graph) {
if (this.graph.isPresent()) {
this.graph.get().addAll(graph);
+
+ graph.getNamespaces().stream()
+ .filter(ns -> !this.graph.get().getNamespace(ns.getPrefix()).isPresent())
+ .forEach(this.graph.get()::setNamespace);
} else {
this.graph = Optional.of(graph);
}
-
+
return this;
}
-
+
/**
* Convenience method used to add a single triple. If an RDF graph is already present, the triple
* will be added to the existing graph.
- *
+ *
* @param subject the subject
* @param predicate the predicate
* @param object the object
@@ -342,13 +346,13 @@ public Builder addTriple(Resource subject, IRI predicate, Value object) {
} else {
this.graph = Optional.of(new ModelBuilder().add(subject, predicate, object).build());
}
-
+
return this;
}
-
+
/**
* Constructs and returns a ThingDescription.
- *
+ *
* @return the constructed ThingDescription
*/
public ThingDescription build() {
diff --git a/src/main/java/ch/unisg/ics/interactions/wot/td/affordances/ActionAffordance.java b/src/main/java/ch/unisg/ics/interactions/wot/td/affordances/ActionAffordance.java
index 3bf22a36..f47a2c7f 100644
--- a/src/main/java/ch/unisg/ics/interactions/wot/td/affordances/ActionAffordance.java
+++ b/src/main/java/ch/unisg/ics/interactions/wot/td/affordances/ActionAffordance.java
@@ -1,79 +1,75 @@
package ch.unisg.ics.interactions.wot.td.affordances;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-
import ch.unisg.ics.interactions.wot.td.schemas.DataSchema;
import ch.unisg.ics.interactions.wot.td.vocabularies.TD;
+import java.util.*;
+
/**
* TODO: add javadoc
- *
- * @author Andrei Ciortea
*
+ * @author Andrei Ciortea
*/
public class ActionAffordance extends InteractionAffordance {
final private Optional input;
final private Optional output;
-
+
// TODO: add safe, idempotent
-
- private ActionAffordance(Optional name, Optional title, List types,
- List