Skip to content
This repository has been archived by the owner on Jun 22, 2023. It is now read-only.

Commit

Permalink
feat(schema): Move skos:broader from DefinedTerm to DefinedTermSet
Browse files Browse the repository at this point in the history
After using the previous model we realised that it made more sense to
have a DTS as the equivalent of an annotation "motivation", and use a
related term as the annotation's body.
This moves broaderUrl and broaderMotivation from DT to DTS, and changes
supporting code
  • Loading branch information
alastair committed Jul 13, 2021
1 parent 086a197 commit 2664028
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 55 deletions.
6 changes: 0 additions & 6 deletions src/routes/helpers/jsonld/DefinedTerm.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,6 @@
],
"inDefinedTermSet": [
"https://pending.schema.org/inDefinedTermSet"
],
"broaderUrl": [
"http://www.w3.org/2004/02/skos/core#broader"
],
"broaderMotivation": [
"http://www.w3.org/2004/02/skos/core#broader"
]
}
}
6 changes: 6 additions & 0 deletions src/routes/helpers/jsonld/DefinedTermSet.json
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@
],
"hasDefinedTerm": [
"https://pending.schema.org/hasDefinedTerm"
],
"broaderUrl": [
"http://www.w3.org/2004/02/skos/core#broader"
],
"broaderMotivation": [
"http://www.w3.org/2004/02/skos/core#broader"
]
}
}
56 changes: 26 additions & 30 deletions src/routes/helpers/transformer.test.js
Original file line number Diff line number Diff line change
@@ -1,123 +1,119 @@
import {preprocessDefinedTerm, transformJsonLD} from "./transformers";
import {preprocessDefinedTermSet, transformJsonLD} from "./transformers";
import { DateTime } from 'neo4j-driver/lib/temporal-types'


describe('definedTermTest', function () {
describe('definedTermSetTest', function () {
const sampleDocument = {
"broaderMotivation": "commenting",
"modified": new DateTime(2021, 6, 22, 10, 50, 24, 292000000, 0, null),
"broaderUrl": null,
"identifier": "77c376dd-009b-4460-a94c-ade21b1aa772",
"image": "https://alastair.trompa-solid.upf.edu/annotation-images/slur.png",
"additionalProperty": [],
"creator": "https://alastair.trompa-solid.upf.edu/profile/card#me",
"created": new DateTime(2021, 6, 22, 10, 50, 24, 292000000, 0, null),
"additionalType": [
"https://vocab.trompamusic.eu/vocab#AnnotationMotivationCollectionElement",
"http://www.w3.org/ns/oa#Motivation"
],
"potentialAction": [],
"inDefinedTermSet": [
"hasDefinedTerm": [
"http://localhost:4000/7c0e9ac0-942a-422a-89b8-884444da6b5a"
],
"termCode": "Slur"
"name": "Performance Directions"
}

it('generates jsonld using broaderMotivation', function() {
const response = transformJsonLD("DefinedTerm", sampleDocument);
const response = transformJsonLD("DefinedTermSet", sampleDocument, "http://localhost:4000");
expect(response["skos:broader"]).toEqual("oa:commenting");
})

it('generates jsonld using broaderUrl', function() {
sampleDocument["broaderMotivation"] = null;
sampleDocument["broaderUrl"] = "https://example.com#motivation";
const response = transformJsonLD("DefinedTerm", sampleDocument);
const response = transformJsonLD("DefinedTermSet", sampleDocument, "http://localhost:4000");
expect(response["skos:broader"]).toEqual("https://example.com#motivation");
})

it('Adds oa:Motivation additionalType if broader enum is present and type is not set', function () {
const definedTerm = {
const definedTermSet = {
"broaderMotivation": "commenting",
"broaderUrl": null,
"additionalProperty": [],
"additionalType": [
"https://vocab.trompamusic.eu/vocab#AnnotationMotivationCollectionElement"
],
"inDefinedTermSet": [
"hasDefinedTerm": [
"http://localhost:4000/7c0e9ac0-942a-422a-89b8-884444da6b5a"
],
"termCode": "Slur"
"name": "Performance Directions"
}
const result = preprocessDefinedTerm(definedTerm);
const result = preprocessDefinedTermSet(definedTermSet);
expect(result["additionalType"].includes("https://www.w3.org/ns/oa#Motivation")).toEqual(true);
expect(result["additionalType"].length).toEqual(2);
});

it('Adds oa:Motivation additionalType if broader url is present and type is not set', function () {
const definedTerm = {
const definedTermSet = {
"broaderMotivation": null,
"broaderUrl": "https://example.com#Motivation",
"additionalProperty": [],
"additionalType": [
"https://vocab.trompamusic.eu/vocab#AnnotationMotivationCollectionElement"
],
"inDefinedTermSet": [
"hasDefinedTerm": [
"http://localhost:4000/7c0e9ac0-942a-422a-89b8-884444da6b5a"
],
"termCode": "Slur"
"name": "Performance Directions"
}
const result = preprocessDefinedTerm(definedTerm);
const result = preprocessDefinedTermSet(definedTermSet);
expect(result["additionalType"].includes("https://www.w3.org/ns/oa#Motivation")).toEqual(true);
expect(result["additionalType"].length).toEqual(2);
});

it("Doesn't add oa:Motivation additionalType if it already exists", function () {
const definedTerm = {
const definedTermSet = {
"broaderMotivation": null,
"broaderUrl": "https://example.com#Motivation",
"additionalProperty": [],
"additionalType": [
"https://vocab.trompamusic.eu/vocab#AnnotationMotivationCollectionElement",
"http://www.w3.org/ns/oa#Motivation"
],
"inDefinedTermSet": [
"hasDefinedTerm": [
"http://localhost:4000/7c0e9ac0-942a-422a-89b8-884444da6b5a"
],
"termCode": "Slur"
"name": "Performance Directions"
}
const result = preprocessDefinedTerm(definedTerm);
const result = preprocessDefinedTermSet(definedTermSet);
expect(result["additionalType"].includes("http://www.w3.org/ns/oa#Motivation")).toEqual(true);
expect(result["additionalType"].includes("https://www.w3.org/ns/oa#Motivation")).toEqual(false);
expect(result["additionalType"].length).toEqual(2);
});

it("Doesn't add oa:Motivation additionalType if broader isn't set", function () {
const definedTerm = {
const definedTermSet = {
"broaderMotivation": null,
"broaderUrl": null,
"additionalProperty": [],
"additionalType": null,
"inDefinedTermSet": [
"hasDefinedTerm": [
"http://localhost:4000/7c0e9ac0-942a-422a-89b8-884444da6b5a"
],
"termCode": "Slur"
"name": "Performance Directions"
}
const result = preprocessDefinedTerm(definedTerm);
const result = preprocessDefinedTermSet(definedTermSet);
expect(result["additionalType"]).toEqual(null);
});

it('Prefixes motivation enums with oa: namespace', function () {
const definedTerm = {
const definedTermSet = {
"broaderMotivation": "commenting",
"broaderUrl": null,
"additionalProperty": [],
"additionalType": null,
"inDefinedTermSet": [
"hasDefinedTerm": [
"http://localhost:4000/7c0e9ac0-942a-422a-89b8-884444da6b5a"
],
"termCode": "Slur"
"name": "Performance Directions"
}
const result = preprocessDefinedTerm(definedTerm);
const result = preprocessDefinedTermSet(definedTermSet);
expect(result["broaderMotivation"]).toEqual("oa:commenting");
});
});
Expand Down
10 changes: 5 additions & 5 deletions src/routes/helpers/transformers.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ export const transformJsonLD = (type, data, baseUrl) => {
throw new Error(`JSON LD not supported for type "${type}"`)
}

if (type === "DefinedTerm") {
data = preprocessDefinedTerm(data);
if (type === "DefinedTermSet") {
data = preprocessDefinedTermSet(data);
}

if (type === "ItemList") {
Expand Down Expand Up @@ -222,14 +222,14 @@ export function preprocessItemList(data, baseUrl) {


/**
* Preprocess data for a DefinedTerm before converting to JSON-LD.
* If a DefinedTerm has a motivation set (either broaderMotivation or
* Preprocess data for a DefinedTermSet before converting to JSON-LD.
* If a DefinedTermSet has a motivation set (either broaderMotivation or
* broaderUrl), then add oa:Motivation to additionalTypes.
*
* If broaderMotivation is set (graphql enum), prefix it with the oa: namespace.
* @param data the result from document.getDocument
*/
export function preprocessDefinedTerm(data) {
export function preprocessDefinedTermSet(data) {
const additionalType = data["additionalType"];
const hasMotivationAdditionalType = additionalType && (additionalType.includes("http://www.w3.org/ns/oa#Motivation") ||
additionalType.includes("https://www.w3.org/ns/oa#Motivation"))
Expand Down
4 changes: 2 additions & 2 deletions src/schema/type/Annotation.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ type Annotation implements ThingInterface & ProvenanceEntityInterface {
"An external resource that this annotation is about"
targetUrl: [String]
# An annotation should always have a motivation. If you want to use a more specific
# annotation from a toolkit (a DefinedTerm) then you can include it, but you should
# annotation from a toolkit (a DefinedTermSet) then you can include it, but you should
# still add the base motivation.
"http://www.w3.org/ns/oa#Motivation"
motivationDefinedTerm: DefinedTerm @relation(name: "ANNOTATON_MOTIVATION_DEFINED_TERM", direction: OUT)
motivationDefinedTermSet: DefinedTermSet @relation(name: "ANNOTATON_MOTIVATION_DEFINED_TERM_SET", direction: OUT)
"http://www.w3.org/ns/oa#Motivation"
motivation: AnnotationMotivation!
motivationUrl: [String]
Expand Down
12 changes: 0 additions & 12 deletions src/schema/type/DefinedTerm.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,4 @@ type DefinedTerm implements ThingInterface {
# TODO: This should only be a relation to one DefinedTermSet
"https://pending.schema.org/inDefinedTermSet"
inDefinedTermSet: [DefinedTermSet] @relation(name: "HAS_DEFINED_TERM", direction: IN)

#######################
### SKOS properties ###
# When we use a DefinedTerm to refer to an annotation motivation, we have to add the motivation
# of which this term is a more specific version of to skos:broader. If you do this, you should
# also add http://www.w3.org/ns/oa#Motivation as an additionalType
# If this DefinedTerm has a standard motivations as its broader value, set an enum in
# broaderMotivation. If it's a third party URL, use broaderUrl.
"http://www.w3.org/2004/02/skos/core#broader"
broaderUrl: String
"http://www.w3.org/2004/02/skos/core#broader"
broaderMotivation: AnnotationMotivation
}
10 changes: 10 additions & 0 deletions src/schema/type/DefinedTermSet.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ type DefinedTermSet implements CreativeWorkInterface & ThingInterface {
"http://www.w3.org/2004/02/skos/core#relatedMatch"
relatedMatch: [ThingInterface] @relation(name: "RELATED_MATCH", direction: OUT)

# When we use a DefinedTermSet to refer to an annotation motivation, we have to add the motivation
# of which this term is a more specific version of to skos:broader. If you do this, you should
# also add http://www.w3.org/ns/oa#Motivation as an additionalType
# If this DefinedTerm has a standard motivations as its broader value, set an enum in
# broaderMotivation. If it's a third party URL, use broaderUrl.
"http://www.w3.org/2004/02/skos/core#broader"
broaderUrl: String
"http://www.w3.org/2004/02/skos/core#broader"
broaderMotivation: AnnotationMotivation

############################################
### ProvenanceEntityInterface properties ###
"http://www.w3.org/ns/prov#wasGeneratedBy"
Expand Down

0 comments on commit 2664028

Please sign in to comment.