From 1b625965835ea1814e2e4534153142dc426f0f79 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Tue, 31 Oct 2017 14:57:01 -0400 Subject: [PATCH 01/22] stub out dataset in json-ld format #3793 --- .../edu/harvard/iq/dataverse/DatasetPage.java | 5 +- .../iq/dataverse/dataset/DatasetUtil.java | 89 +++++++++++++++++++ src/main/webapp/dataset.xhtml | 5 ++ src/main/webapp/dataverse_template.xhtml | 1 + 4 files changed, 99 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 030553916d3..fbdb53cbbcd 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -3984,5 +3984,8 @@ public List getDatasetSummaryFields() { return DatasetUtil.getDatasetSummaryFields(workingVersion, customFields); } - + + public String getJsonLd() { + return DatasetUtil.getJsonLd(workingVersion); + } } diff --git a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java index 101c5fb7804..156774172a7 100644 --- a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java +++ b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java @@ -2,9 +2,13 @@ import edu.harvard.iq.dataverse.DataFile; import edu.harvard.iq.dataverse.Dataset; +import edu.harvard.iq.dataverse.DatasetAuthor; import edu.harvard.iq.dataverse.DatasetField; import edu.harvard.iq.dataverse.DatasetVersion; import edu.harvard.iq.dataverse.FileMetadata; +import edu.harvard.iq.dataverse.authorization.AuthenticatedUserDisplayInfo; +import edu.harvard.iq.dataverse.authorization.providers.shib.ShibUserNameFields; +import edu.harvard.iq.dataverse.authorization.providers.shib.ShibUtil; import edu.harvard.iq.dataverse.dataaccess.DataAccess; import static edu.harvard.iq.dataverse.dataaccess.DataAccess.getStorageIO; import edu.harvard.iq.dataverse.dataaccess.StorageIO; @@ -33,6 +37,9 @@ import java.util.HashSet; import java.util.Map; import javax.imageio.ImageIO; +import javax.json.Json; +import javax.json.JsonArrayBuilder; +import javax.json.JsonObjectBuilder; import org.apache.commons.io.IOUtils; public class DatasetUtil { @@ -416,4 +423,86 @@ public static List getDatasetSummaryFields(DatasetVersion datasetV return datasetFields; } +/* +{ + "@context": "http://schema.org", + "@type": "Dataset", + "@id": "https://doi.org/10.7910/dvn/icfngt", + "additionalType": "Dataset", + "name": "Replication Data for: Parties, Legislators, and the Origins of Proportional Representation", + "author": [ + { + "@type": "Person", + "name": "Gary W. Cox", + "givenName": "Gary W.", + "familyName": "Cox" + }, + { + "@type": "Person", + "name": "Jon H. Fiva", + "givenName": "Jon H.", + "familyName": "Fiva" + }, + { + "@type": "Person", + "name": "Daniel M. Smith", + "givenName": "Daniel M.", + "familyName": "Smith" + } + ], + "datePublished": "2017", + "schemaVersion": "http://datacite.org/schema/kernel-4", + "publisher": { + "@type": "Organization", + "name": "Harvard Dataverse" + }, + "provider": { + "@type": "Organization", + "name": "DataCite" + } +} +*/ + public static String getJsonLd(DatasetVersion workingVersion) { + JsonObjectBuilder job = Json.createObjectBuilder(); + job.add("@context", "http://schema.org"); + job.add("@type", "Dataset"); + // FIXME + job.add("@id", "https://doi.org/10.7910/dvn/icfngt"); + job.add("additionalType", "Dataset"); + job.add("name", workingVersion.getTitle()); + job.add("@context", "http://schema.org"); + JsonArrayBuilder authors = Json.createArrayBuilder(); + for (DatasetAuthor datasetAuthor : workingVersion.getDatasetAuthors()) { + JsonObjectBuilder author = Json.createObjectBuilder(); + author.add("@type", "Person"); + ShibUserNameFields shibUserNameFields = ShibUtil.findBestFirstAndLastName(null, null, datasetAuthor.getName().getValue().replaceAll(",", "")); + AuthenticatedUserDisplayInfo displayInfo = new AuthenticatedUserDisplayInfo( + shibUserNameFields.getFirstName(), + shibUserNameFields.getLastName(), + "", + "", + "" + ); + author.add("name", displayInfo.getFirstName() + " " + displayInfo.getLastName()); + author.add("givenName", displayInfo.getFirstName()); + author.add("familyName", displayInfo.getLastName()); + authors.add(author); + } + job.add("author", authors); + // FIXME + job.add("datePublished", "2017"); + job.add("schemaVersion", "http://datacite.org/schema/kernel-4"); + job.add("publisher", Json.createObjectBuilder() + .add("@type", "Organization") + // FIXME + .add("name", "Harvard Dataverse") + ); + job.add("provider", Json.createObjectBuilder() + .add("@type", "Organization") + // FIXME + .add("name", "DataCite") + ); + return job.build().toString(); + } + } diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index 4a71e3b274f..7d1192140b2 100755 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -34,6 +34,11 @@ + + + diff --git a/src/main/webapp/dataverse_template.xhtml b/src/main/webapp/dataverse_template.xhtml index 1d581b1f19d..5726173e328 100644 --- a/src/main/webapp/dataverse_template.xhtml +++ b/src/main/webapp/dataverse_template.xhtml @@ -14,6 +14,7 @@ <h:outputText value="#{pageTitle}"/> + From 5ad88fcd33ad0f0a1fb95cc239191216e2fcd60f Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Wed, 1 Nov 2017 13:15:00 -0400 Subject: [PATCH 02/22] better author name parsing (could be an org!) #3793 #2243 --- .../iq/dataverse/dataset/DatasetUtil.java | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java index 156774172a7..e2773b13c93 100644 --- a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java +++ b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java @@ -6,9 +6,6 @@ import edu.harvard.iq.dataverse.DatasetField; import edu.harvard.iq.dataverse.DatasetVersion; import edu.harvard.iq.dataverse.FileMetadata; -import edu.harvard.iq.dataverse.authorization.AuthenticatedUserDisplayInfo; -import edu.harvard.iq.dataverse.authorization.providers.shib.ShibUserNameFields; -import edu.harvard.iq.dataverse.authorization.providers.shib.ShibUtil; import edu.harvard.iq.dataverse.dataaccess.DataAccess; import static edu.harvard.iq.dataverse.dataaccess.DataAccess.getStorageIO; import edu.harvard.iq.dataverse.dataaccess.StorageIO; @@ -474,18 +471,25 @@ public static String getJsonLd(DatasetVersion workingVersion) { JsonArrayBuilder authors = Json.createArrayBuilder(); for (DatasetAuthor datasetAuthor : workingVersion.getDatasetAuthors()) { JsonObjectBuilder author = Json.createObjectBuilder(); - author.add("@type", "Person"); - ShibUserNameFields shibUserNameFields = ShibUtil.findBestFirstAndLastName(null, null, datasetAuthor.getName().getValue().replaceAll(",", "")); - AuthenticatedUserDisplayInfo displayInfo = new AuthenticatedUserDisplayInfo( - shibUserNameFields.getFirstName(), - shibUserNameFields.getLastName(), - "", - "", - "" - ); - author.add("name", displayInfo.getFirstName() + " " + displayInfo.getLastName()); - author.add("givenName", displayInfo.getFirstName()); - author.add("familyName", displayInfo.getLastName()); + // "We expect dataset depositors to put personal names and organizational names in the author field." For example, "Gallup Organization". + String personOrOrganization = datasetAuthor.getName().getValue(); + // TODO: Make this more robust. What if people or orgs have more than one comma in the name? For example, + // "Digital Archive of Massachusetts Anti-Slavery and Anti-Segregation Petitions, Massachusetts Archives, Boston MA" + String[] parts = personOrOrganization.split(","); + String name = ""; + String firstName = null; + String lastName = null; + if (parts.length == 1) { + name = personOrOrganization; + } else { + author.add("@type", "Person"); + lastName = parts[0]; + firstName = parts[1]; + author.add("givenName", firstName); + author.add("familyName", lastName); + name = firstName + " " + lastName; + } + author.add("name", name); authors.add(author); } job.add("author", authors); From 2cc958dbd907c5027ce2d73fe912f0da193ce0b7 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Wed, 1 Nov 2017 13:30:15 -0400 Subject: [PATCH 03/22] fix a number of issues (listed below) #3793 #2243 - only show published versions - show URL to DOI dynamically (was hard coded) - show publication date - show correct publisher - show correct provider --- .../iq/dataverse/dataset/DatasetUtil.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java index e2773b13c93..0cc6f494f6f 100644 --- a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java +++ b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java @@ -459,12 +459,16 @@ public static List getDatasetSummaryFields(DatasetVersion datasetV } } */ + // TODO: Make this more performant by writing the output to the database or a file? public static String getJsonLd(DatasetVersion workingVersion) { + // We show published datasets only for "datePublished" field below. + if (workingVersion.isDraft()) { + return ""; + } JsonObjectBuilder job = Json.createObjectBuilder(); job.add("@context", "http://schema.org"); job.add("@type", "Dataset"); - // FIXME - job.add("@id", "https://doi.org/10.7910/dvn/icfngt"); + job.add("@id", workingVersion.getDataset().getPersistentURL()); job.add("additionalType", "Dataset"); job.add("name", workingVersion.getTitle()); job.add("@context", "http://schema.org"); @@ -480,6 +484,7 @@ public static String getJsonLd(DatasetVersion workingVersion) { String firstName = null; String lastName = null; if (parts.length == 1) { + // TODO: consider adding "Thing" for the "@type" explicitly here. name = personOrOrganization; } else { author.add("@type", "Person"); @@ -493,18 +498,15 @@ public static String getJsonLd(DatasetVersion workingVersion) { authors.add(author); } job.add("author", authors); - // FIXME - job.add("datePublished", "2017"); + job.add("datePublished", workingVersion.getProductionDate()); job.add("schemaVersion", "http://datacite.org/schema/kernel-4"); job.add("publisher", Json.createObjectBuilder() .add("@type", "Organization") - // FIXME - .add("name", "Harvard Dataverse") + .add("name", workingVersion.getRootDataverseNameforCitation()) ); job.add("provider", Json.createObjectBuilder() .add("@type", "Organization") - // FIXME - .add("name", "DataCite") + .add("name", "Dataverse") ); return job.build().toString(); } From ad71c6aa8b05c3cf6ecf90c1023fba2607acef71 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Thu, 2 Nov 2017 15:17:32 -0400 Subject: [PATCH 04/22] use same date format as meta name="DC.date" #2243 --- .../edu/harvard/iq/dataverse/DatasetPage.java | 17 ----------------- .../harvard/iq/dataverse/DatasetVersion.java | 16 ++++++++++++++++ .../iq/dataverse/dataset/DatasetUtil.java | 2 +- src/main/webapp/dataset.xhtml | 2 +- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index fbdb53cbbcd..ee1a4f67577 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -3864,23 +3864,6 @@ public String getDescription() { return workingVersion.getDescriptionPlainText(); } - /** - * dataset publication date unpublished datasets will return an empty - * string. - * - * @return String dataset publication date (dd MMM yyyy). - */ - public String getPublicationDate() { - assert (null != workingVersion); - if (DatasetVersion.VersionState.DRAFT == workingVersion.getVersionState()) { - return ""; - } - Date rel_date = workingVersion.getReleaseTime(); - SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd"); - String r = fmt.format(rel_date.getTime()); - return r; - } - /** * dataset authors * diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index 9e97e8d475a..c3d0e223c7b 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -1100,4 +1100,20 @@ public List getWorkflowComments() { return workflowComments; } + /** + * dataset publication date unpublished datasets will return an empty + * string. + * + * @return String dataset publication date (dd MMM yyyy). + */ + public String getPublicationDate() { + if (DatasetVersion.VersionState.DRAFT == this.getVersionState()) { + return ""; + } + Date rel_date = this.getReleaseTime(); + SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd"); + String r = fmt.format(rel_date.getTime()); + return r; + } + } diff --git a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java index 0cc6f494f6f..f82addb41b4 100644 --- a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java +++ b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java @@ -498,7 +498,7 @@ public static String getJsonLd(DatasetVersion workingVersion) { authors.add(author); } job.add("author", authors); - job.add("datePublished", workingVersion.getProductionDate()); + job.add("datePublished", workingVersion.getPublicationDate()); job.add("schemaVersion", "http://datacite.org/schema/kernel-4"); job.add("publisher", Json.createObjectBuilder() .add("@type", "Organization") diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index 7d1192140b2..5f3507455e8 100755 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -24,7 +24,7 @@ - + From 80b5a8871e219590e7cc27423160cd5e3b64d7e5 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Thu, 2 Nov 2017 15:19:49 -0400 Subject: [PATCH 05/22] limit to non-published, not just non-drafts #2243 Also add helper method. --- src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java | 4 ++++ .../java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index c3d0e223c7b..acc55b71c82 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -418,6 +418,10 @@ public boolean isReleased() { return versionState.equals(VersionState.RELEASED); } + public boolean isPublished() { + return isReleased(); + } + public boolean isDraft() { return versionState.equals(VersionState.DRAFT); } diff --git a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java index f82addb41b4..4150c580072 100644 --- a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java +++ b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java @@ -462,7 +462,7 @@ public static List getDatasetSummaryFields(DatasetVersion datasetV // TODO: Make this more performant by writing the output to the database or a file? public static String getJsonLd(DatasetVersion workingVersion) { // We show published datasets only for "datePublished" field below. - if (workingVersion.isDraft()) { + if (!workingVersion.isPublished()) { return ""; } JsonObjectBuilder job = Json.createObjectBuilder(); From 485a5ca71a91eb04d1935e3b46f0dc76ded0f15b Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Thu, 2 Nov 2017 15:25:37 -0400 Subject: [PATCH 06/22] don't even try to figure out if the author is a person or not #2243 --- .../iq/dataverse/dataset/DatasetUtil.java | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java index 4150c580072..f93611beea5 100644 --- a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java +++ b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java @@ -475,25 +475,9 @@ public static String getJsonLd(DatasetVersion workingVersion) { JsonArrayBuilder authors = Json.createArrayBuilder(); for (DatasetAuthor datasetAuthor : workingVersion.getDatasetAuthors()) { JsonObjectBuilder author = Json.createObjectBuilder(); - // "We expect dataset depositors to put personal names and organizational names in the author field." For example, "Gallup Organization". String personOrOrganization = datasetAuthor.getName().getValue(); - // TODO: Make this more robust. What if people or orgs have more than one comma in the name? For example, - // "Digital Archive of Massachusetts Anti-Slavery and Anti-Segregation Petitions, Massachusetts Archives, Boston MA" - String[] parts = personOrOrganization.split(","); - String name = ""; - String firstName = null; - String lastName = null; - if (parts.length == 1) { - // TODO: consider adding "Thing" for the "@type" explicitly here. - name = personOrOrganization; - } else { - author.add("@type", "Person"); - lastName = parts[0]; - firstName = parts[1]; - author.add("givenName", firstName); - author.add("familyName", lastName); - name = firstName + " " + lastName; - } + String name = personOrOrganization; + // We are aware of "givenName" and "familyName" but instead of a person it might be an organization such as "Gallup Organization". author.add("name", name); authors.add(author); } From 171c8f3e1c5b340b66900fded3cab53d1180308a Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Thu, 2 Nov 2017 15:29:35 -0400 Subject: [PATCH 07/22] move getJsonLd method to DatasetVersion entity #2243 --- .../edu/harvard/iq/dataverse/DatasetPage.java | 2 +- .../harvard/iq/dataverse/DatasetVersion.java | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index ee1a4f67577..01532cbfd54 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -3969,6 +3969,6 @@ public List getDatasetSummaryFields() { } public String getJsonLd() { - return DatasetUtil.getJsonLd(workingVersion); + return workingVersion.getJsonLd(); } } diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index acc55b71c82..44faaef5664 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -17,6 +17,9 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import javax.json.Json; +import javax.json.JsonArrayBuilder; +import javax.json.JsonObjectBuilder; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; @@ -1120,4 +1123,40 @@ public String getPublicationDate() { return r; } + // TODO: Make this more performant by writing the output to the database or a file? + public String getJsonLd() { + // We show published datasets only for "datePublished" field below. + if (!this.isPublished()) { + return ""; + } + JsonObjectBuilder job = Json.createObjectBuilder(); + job.add("@context", "http://schema.org"); + job.add("@type", "Dataset"); + job.add("@id", this.getDataset().getPersistentURL()); + job.add("additionalType", "Dataset"); + job.add("name", this.getTitle()); + job.add("@context", "http://schema.org"); + JsonArrayBuilder authors = Json.createArrayBuilder(); + for (DatasetAuthor datasetAuthor : this.getDatasetAuthors()) { + JsonObjectBuilder author = Json.createObjectBuilder(); + String personOrOrganization = datasetAuthor.getName().getValue(); + String name = personOrOrganization; + // We are aware of "givenName" and "familyName" but instead of a person it might be an organization such as "Gallup Organization". + author.add("name", name); + authors.add(author); + } + job.add("author", authors); + job.add("datePublished", this.getPublicationDate()); + job.add("schemaVersion", "http://datacite.org/schema/kernel-4"); + job.add("publisher", Json.createObjectBuilder() + .add("@type", "Organization") + .add("name", this.getRootDataverseNameforCitation()) + ); + job.add("provider", Json.createObjectBuilder() + .add("@type", "Organization") + .add("name", "Dataverse") + ); + return job.build().toString(); + } + } From 6c5f0440f04beba54270d882155c34ed8ee28e3a Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Thu, 2 Nov 2017 15:41:12 -0400 Subject: [PATCH 08/22] use dateModified and proper schemaVersion URL #2243 --- src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index 44faaef5664..d34dd24dcdd 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -1146,8 +1146,8 @@ public String getJsonLd() { authors.add(author); } job.add("author", authors); - job.add("datePublished", this.getPublicationDate()); - job.add("schemaVersion", "http://datacite.org/schema/kernel-4"); + job.add("dateModified", this.getPublicationDate()); + job.add("schemaVersion", "https://schema.org/version/3.3"); job.add("publisher", Json.createObjectBuilder() .add("@type", "Organization") .add("name", this.getRootDataverseNameforCitation()) From 8f3083c3d4b900ebcd14fd21ee6298045335da88 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Fri, 3 Nov 2017 11:14:13 -0400 Subject: [PATCH 09/22] delete cruft (unused method) #2243 --- .../iq/dataverse/dataset/DatasetUtil.java | 75 ------------------- 1 file changed, 75 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java index f93611beea5..6b88b7eaae6 100644 --- a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java +++ b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java @@ -420,79 +420,4 @@ public static List getDatasetSummaryFields(DatasetVersion datasetV return datasetFields; } -/* -{ - "@context": "http://schema.org", - "@type": "Dataset", - "@id": "https://doi.org/10.7910/dvn/icfngt", - "additionalType": "Dataset", - "name": "Replication Data for: Parties, Legislators, and the Origins of Proportional Representation", - "author": [ - { - "@type": "Person", - "name": "Gary W. Cox", - "givenName": "Gary W.", - "familyName": "Cox" - }, - { - "@type": "Person", - "name": "Jon H. Fiva", - "givenName": "Jon H.", - "familyName": "Fiva" - }, - { - "@type": "Person", - "name": "Daniel M. Smith", - "givenName": "Daniel M.", - "familyName": "Smith" - } - ], - "datePublished": "2017", - "schemaVersion": "http://datacite.org/schema/kernel-4", - "publisher": { - "@type": "Organization", - "name": "Harvard Dataverse" - }, - "provider": { - "@type": "Organization", - "name": "DataCite" - } -} -*/ - // TODO: Make this more performant by writing the output to the database or a file? - public static String getJsonLd(DatasetVersion workingVersion) { - // We show published datasets only for "datePublished" field below. - if (!workingVersion.isPublished()) { - return ""; - } - JsonObjectBuilder job = Json.createObjectBuilder(); - job.add("@context", "http://schema.org"); - job.add("@type", "Dataset"); - job.add("@id", workingVersion.getDataset().getPersistentURL()); - job.add("additionalType", "Dataset"); - job.add("name", workingVersion.getTitle()); - job.add("@context", "http://schema.org"); - JsonArrayBuilder authors = Json.createArrayBuilder(); - for (DatasetAuthor datasetAuthor : workingVersion.getDatasetAuthors()) { - JsonObjectBuilder author = Json.createObjectBuilder(); - String personOrOrganization = datasetAuthor.getName().getValue(); - String name = personOrOrganization; - // We are aware of "givenName" and "familyName" but instead of a person it might be an organization such as "Gallup Organization". - author.add("name", name); - authors.add(author); - } - job.add("author", authors); - job.add("datePublished", workingVersion.getPublicationDate()); - job.add("schemaVersion", "http://datacite.org/schema/kernel-4"); - job.add("publisher", Json.createObjectBuilder() - .add("@type", "Organization") - .add("name", workingVersion.getRootDataverseNameforCitation()) - ); - job.add("provider", Json.createObjectBuilder() - .add("@type", "Organization") - .add("name", "Dataverse") - ); - return job.build().toString(); - } - } From b1db8ee00207d9ca5a3ea1459268bfbae12f8cf9 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Fri, 3 Nov 2017 11:26:37 -0400 Subject: [PATCH 10/22] rename to publicationDateAsString and improve javadoc #2243 --- .../edu/harvard/iq/dataverse/DatasetVersion.java | 15 ++++++++++++--- src/main/webapp/dataset.xhtml | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index d34dd24dcdd..954e284bb0a 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -1111,9 +1111,9 @@ public List getWorkflowComments() { * dataset publication date unpublished datasets will return an empty * string. * - * @return String dataset publication date (dd MMM yyyy). + * @return String dataset publication date in ISO 8601 format (yyyy-MM-dd). */ - public String getPublicationDate() { + public String getPublicationDateAsString() { if (DatasetVersion.VersionState.DRAFT == this.getVersionState()) { return ""; } @@ -1146,7 +1146,16 @@ public String getJsonLd() { authors.add(author); } job.add("author", authors); - job.add("dateModified", this.getPublicationDate()); + /** + * We are aware that there is a "datePublished" field but it means "Date + * of first broadcast/publication." This only makes sense for a 1.0 + * version. + * + * "dateModified" is more appropriate for a version: "The date on which + * the CreativeWork was most recently modified or when the item's entry + * was modified within a DataFeed." + */ + job.add("dateModified", this.getPublicationDateAsString()); job.add("schemaVersion", "https://schema.org/version/3.3"); job.add("publisher", Json.createObjectBuilder() .add("@type", "Organization") diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index 5f3507455e8..9ae9c42a173 100755 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -24,7 +24,7 @@ - + From f8ca59f32ee4d6f81a348a35b31859d9bf96a1a4 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Fri, 3 Nov 2017 12:13:05 -0400 Subject: [PATCH 11/22] add tests for getJsonLd and getPublicationDateAsString #2243 --- .../iq/dataverse/DatasetVersionTest.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java b/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java index 5b51eceb858..ed99121b53c 100644 --- a/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java @@ -1,9 +1,16 @@ package edu.harvard.iq.dataverse; import edu.harvard.iq.dataverse.mocks.MocksFactory; +import java.io.StringReader; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Collections; import java.util.List; +import javax.json.Json; +import javax.json.JsonArray; +import javax.json.JsonObject; +import javax.json.JsonReader; import org.junit.After; import org.junit.AfterClass; import static org.junit.Assert.assertEquals; @@ -85,4 +92,40 @@ public void testIsInReview() { assertFalse(nonDraft.isInReview()); } + @Test + public void testGetJsonLd() throws ParseException { + Dataset dataset = new Dataset(); + dataset.setProtocol("doi"); + dataset.setAuthority("10.5072/FK2"); + dataset.setIdentifier("LK0D1H"); + DatasetVersion datasetVersion = new DatasetVersion(); + datasetVersion.setDataset(dataset); + datasetVersion.setVersionState(DatasetVersion.VersionState.DRAFT); + assertEquals("", datasetVersion.getPublicationDateAsString()); + // Only published datasets return any JSON. + assertEquals("", datasetVersion.getJsonLd()); + datasetVersion.setVersionState(DatasetVersion.VersionState.RELEASED); + SimpleDateFormat dateFmt = new SimpleDateFormat("yyyyMMdd"); + datasetVersion.setReleaseTime(dateFmt.parse("19551105")); + Dataverse dataverse = new Dataverse(); + dataverse.setName("LibraScholar"); + dataset.setOwner(dataverse); + String jsonLd = datasetVersion.getJsonLd(); + System.out.println("jsonLd: " + jsonLd); + JsonReader jsonReader = Json.createReader(new StringReader(jsonLd)); + JsonObject obj = jsonReader.readObject(); + assertEquals("http://schema.org", obj.getString("@context")); + assertEquals("Dataset", obj.getString("@type")); + assertEquals("http://dx.doi.org/10.5072/FK2/LK0D1H", obj.getString("@id")); + assertEquals("https://schema.org/version/3.3", obj.getString("schemaVersion")); + assertEquals("1955-11-05", obj.getString("dateModified")); + // TODO: if it ever becomes easier to mock a dataset title, test it. + assertEquals("", obj.getString("name")); + // TODO: If it ever becomes easier to mock authors, test them. + JsonArray emptyArray = Json.createArrayBuilder().build(); + assertEquals(emptyArray, obj.getJsonArray("author")); + assertEquals("Dataverse", obj.getJsonObject("provider").getString("name")); + assertEquals("LibraScholar", obj.getJsonObject("publisher").getString("name")); + } + } From 1aa323a0d94d3f31b3befdb2c188326bffda4f7a Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Fri, 3 Nov 2017 12:20:52 -0400 Subject: [PATCH 12/22] remove unused imports used in this branch #2243 --- .../java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java index 6b88b7eaae6..101c5fb7804 100644 --- a/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java +++ b/src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java @@ -2,7 +2,6 @@ import edu.harvard.iq.dataverse.DataFile; import edu.harvard.iq.dataverse.Dataset; -import edu.harvard.iq.dataverse.DatasetAuthor; import edu.harvard.iq.dataverse.DatasetField; import edu.harvard.iq.dataverse.DatasetVersion; import edu.harvard.iq.dataverse.FileMetadata; @@ -34,9 +33,6 @@ import java.util.HashSet; import java.util.Map; import javax.imageio.ImageIO; -import javax.json.Json; -import javax.json.JsonArrayBuilder; -import javax.json.JsonObjectBuilder; import org.apache.commons.io.IOUtils; public class DatasetUtil { From c9417815d896a4a385b9a4968453ba23e1f631c4 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Fri, 3 Nov 2017 12:21:12 -0400 Subject: [PATCH 13/22] explain why ui:insert lines are in the template #2243 --- src/main/webapp/dataverse_template.xhtml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/webapp/dataverse_template.xhtml b/src/main/webapp/dataverse_template.xhtml index 5726173e328..d082b3cb77d 100644 --- a/src/main/webapp/dataverse_template.xhtml +++ b/src/main/webapp/dataverse_template.xhtml @@ -13,6 +13,7 @@ <h:outputText value="#{pageTitle}"/> + From 8c74e376412ab0a14aed3c1b48fb5720460f2f6c Mon Sep 17 00:00:00 2001 From: Leonid Andreev Date: Mon, 6 Nov 2017 21:28:06 -0500 Subject: [PATCH 14/22] A few quick fixes for getJsonLd() (and the corresponding test in DatasetVersionTest()); (ref #2243) --- .../harvard/iq/dataverse/DatasetVersion.java | 42 +++++++++++++++++-- .../iq/dataverse/DatasetVersionTest.java | 10 ++++- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index 954e284bb0a..c58b946ed9d 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -1133,9 +1133,7 @@ public String getJsonLd() { job.add("@context", "http://schema.org"); job.add("@type", "Dataset"); job.add("@id", this.getDataset().getPersistentURL()); - job.add("additionalType", "Dataset"); job.add("name", this.getTitle()); - job.add("@context", "http://schema.org"); JsonArrayBuilder authors = Json.createArrayBuilder(); for (DatasetAuthor datasetAuthor : this.getDatasetAuthors()) { JsonObjectBuilder author = Json.createObjectBuilder(); @@ -1150,17 +1148,55 @@ public String getJsonLd() { * We are aware that there is a "datePublished" field but it means "Date * of first broadcast/publication." This only makes sense for a 1.0 * version. - * + * (Per @jggautier's comment 03/11/2017 in #2243, we are putting datePublished + * back -- L.A.) + */ + job.add("datePublished", this.getDataset().getPublicationDateFormattedYYYYMMDD()); + + /** * "dateModified" is more appropriate for a version: "The date on which * the CreativeWork was most recently modified or when the item's entry * was modified within a DataFeed." */ job.add("dateModified", this.getPublicationDateAsString()); + job.add("version", this.getVersionNumber().toString()); + /** + * "keywords" - contains subject(s), datasetkeyword(s) and topicclassification(s) + * metadata fields for the version. -- L.A. + * TODO (see #2243 for details on how to format) + */ + + /** + * citation: + */ + JsonObjectBuilder citation = Json.createObjectBuilder(); + citation.add("@type", "Dataset"); + citation.add("text", this.getCitation()); + job.add("citation", citation); + /* TODO: should we use the HTML-style citation, i.e. this.getCitation(true) instead -- L.A.?) */ + + /** + * temporalCoverage: + * TODO (if available) + */ + + /** + * spatialCoverage: + * TODO (if available) + */ + + /** + * "funder": + * TODO + * (see 2243 for info on how to format -- L.A.) + */ + job.add("schemaVersion", "https://schema.org/version/3.3"); job.add("publisher", Json.createObjectBuilder() .add("@type", "Organization") .add("name", this.getRootDataverseNameforCitation()) ); + job.add("provider", Json.createObjectBuilder() .add("@type", "Organization") .add("name", "Dataverse") diff --git a/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java b/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java index ed99121b53c..4f9be1c929c 100644 --- a/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java @@ -2,10 +2,12 @@ import edu.harvard.iq.dataverse.mocks.MocksFactory; import java.io.StringReader; +import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Collections; +import java.util.Date; import java.util.List; import javax.json.Json; import javax.json.JsonArray; @@ -105,8 +107,11 @@ public void testGetJsonLd() throws ParseException { // Only published datasets return any JSON. assertEquals("", datasetVersion.getJsonLd()); datasetVersion.setVersionState(DatasetVersion.VersionState.RELEASED); + datasetVersion.setVersionNumber(1L); SimpleDateFormat dateFmt = new SimpleDateFormat("yyyyMMdd"); - datasetVersion.setReleaseTime(dateFmt.parse("19551105")); + Date publicationDate = dateFmt.parse("19551105"); + datasetVersion.setReleaseTime(publicationDate); + dataset.setPublicationDate(new Timestamp(publicationDate.getTime())); Dataverse dataverse = new Dataverse(); dataverse.setName("LibraScholar"); dataset.setOwner(dataverse); @@ -119,6 +124,8 @@ public void testGetJsonLd() throws ParseException { assertEquals("http://dx.doi.org/10.5072/FK2/LK0D1H", obj.getString("@id")); assertEquals("https://schema.org/version/3.3", obj.getString("schemaVersion")); assertEquals("1955-11-05", obj.getString("dateModified")); + assertEquals("1955-11-05", obj.getString("datePublished")); + assertEquals("1", obj.getString("version")); // TODO: if it ever becomes easier to mock a dataset title, test it. assertEquals("", obj.getString("name")); // TODO: If it ever becomes easier to mock authors, test them. @@ -126,6 +133,7 @@ public void testGetJsonLd() throws ParseException { assertEquals(emptyArray, obj.getJsonArray("author")); assertEquals("Dataverse", obj.getJsonObject("provider").getString("name")); assertEquals("LibraScholar", obj.getJsonObject("publisher").getString("name")); + assertEquals(datasetVersion.getCitation(), obj.getJsonObject("citation").getString("text")); } } From 9f1d0573443a72716988a7f54b866fae7c3805d8 Mon Sep 17 00:00:00 2001 From: Leonid Andreev Date: Mon, 6 Nov 2017 21:58:32 -0500 Subject: [PATCH 15/22] one more addition for #2243 - added temporalCoverage. --- .../harvard/iq/dataverse/DatasetVersion.java | 54 +++++++++++++++++-- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index c58b946ed9d..ed9297c6415 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -714,6 +714,39 @@ public List getDatasetAuthors() { return retList; } + public List getTimePeriodsCovered() { + List retList = new ArrayList<>(); + for (DatasetField dsf : this.getDatasetFields()) { + if (dsf.getDatasetFieldType().getName().equals(DatasetFieldConstant.timePeriodCovered)) { + for (DatasetFieldCompoundValue timePeriodValue : dsf.getDatasetFieldCompoundValues()) { + String start = ""; + String end = ""; + for (DatasetField subField : timePeriodValue.getChildDatasetFields()) { + if (subField.getDatasetFieldType().getName().equals(DatasetFieldConstant.timePeriodCoveredStart)) { + if (subField.isEmptyForDisplay()) { + start = null; + } else { + start = subField.getDisplayValue(); + } + } + if (subField.getDatasetFieldType().getName().equals(DatasetFieldConstant.timePeriodCoveredEnd)) { + if (subField.isEmptyForDisplay()) { + end = null; + } else { + end = subField.getDisplayValue(); + } + } + + } + if (start != null && end != null) { + retList.add(start + "/" + end); + } + } + } + } + return retList; + } + /** * @return List of Strings containing the names of the authors. */ @@ -1151,7 +1184,10 @@ public String getJsonLd() { * (Per @jggautier's comment 03/11/2017 in #2243, we are putting datePublished * back -- L.A.) */ - job.add("datePublished", this.getDataset().getPublicationDateFormattedYYYYMMDD()); + String datePublished = this.getDataset().getPublicationDateFormattedYYYYMMDD(); + if (datePublished != null) { + job.add("datePublished", datePublished); + } /** * "dateModified" is more appropriate for a version: "The date on which @@ -1173,16 +1209,26 @@ public String getJsonLd() { citation.add("@type", "Dataset"); citation.add("text", this.getCitation()); job.add("citation", citation); - /* TODO: should we use the HTML-style citation, i.e. this.getCitation(true) instead -- L.A.?) */ + /* should we use the HTML-style citation, i.e. this.getCitation(true) instead -- L.A.?) */ /** * temporalCoverage: - * TODO (if available) + * (if available) */ + List timePeriodsCovered = this.getTimePeriodsCovered(); + if (timePeriodsCovered.size() > 0) { + JsonArrayBuilder temporalCoverage = Json.createArrayBuilder(); + for (String timePeriod : timePeriodsCovered) { + temporalCoverage.add(timePeriod); + } + job.add("temporalCoverage", temporalCoverage); + } + /** * spatialCoverage: - * TODO (if available) + * (if available) + * TODO */ /** From 7d03e70c7d06329e6851160410cb251171b804b3 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Tue, 7 Nov 2017 16:21:37 -0500 Subject: [PATCH 16/22] consistency between DC.subject and JSON-LD keywords #2243 --- .../java/edu/harvard/iq/dataverse/DatasetPage.java | 10 ---------- .../edu/harvard/iq/dataverse/DatasetVersion.java | 13 ++++++++++--- src/main/webapp/dataset.xhtml | 2 +- .../harvard/iq/dataverse/DatasetVersionTest.java | 2 ++ 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 01532cbfd54..64d0012d4b9 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -3874,16 +3874,6 @@ public List getDatasetAuthors() { return workingVersion.getDatasetAuthorNames(); } - /** - * dataset subjects - * - * @return array of String containing the subjects for a page - */ - public List getDatasetSubjects() { - assert (null != workingVersion); - return workingVersion.getDatasetSubjects(); - } - /** * publisher (aka - name of root dataverse) * diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index ed9297c6415..3093b39175c 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -1197,10 +1197,17 @@ public String getJsonLd() { job.add("dateModified", this.getPublicationDateAsString()); job.add("version", this.getVersionNumber().toString()); /** - * "keywords" - contains subject(s), datasetkeyword(s) and topicclassification(s) - * metadata fields for the version. -- L.A. - * TODO (see #2243 for details on how to format) + * "keywords" - We are using getDatasetSubjects() for consistency with + * `meta name="DC.subject"` in the dataset "head" tag. Per #2243 in the + * future, we could consider adding datasetkeyword(s) and + * topicclassification(s) but we should keep it consistent with + * "DC.subject". */ + JsonArrayBuilder keywords = Json.createArrayBuilder(); + this.getDatasetSubjects().forEach((subjects) -> { + keywords.add(subjects); + }); + job.add("keywords", keywords); /** * citation: diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index 9ae9c42a173..31eec38efc3 100755 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -30,7 +30,7 @@ - + diff --git a/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java b/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java index 4f9be1c929c..12550f14665 100644 --- a/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java @@ -131,6 +131,8 @@ public void testGetJsonLd() throws ParseException { // TODO: If it ever becomes easier to mock authors, test them. JsonArray emptyArray = Json.createArrayBuilder().build(); assertEquals(emptyArray, obj.getJsonArray("author")); + // TODO: If it ever becomes easier to mock subjects, test them. + assertEquals(emptyArray, obj.getJsonArray("keywords")); assertEquals("Dataverse", obj.getJsonObject("provider").getString("name")); assertEquals("LibraScholar", obj.getJsonObject("publisher").getString("name")); assertEquals(datasetVersion.getCitation(), obj.getJsonObject("citation").getString("text")); From 8b8391f92b8c97950016cb40a336ca9307302c42 Mon Sep 17 00:00:00 2001 From: Leonid Andreev Date: Wed, 15 Nov 2017 13:24:22 -0500 Subject: [PATCH 17/22] added topicClassifications and kewords to JSONLD. (#2243) --- .../harvard/iq/dataverse/DatasetVersion.java | 90 +++++++++++++++++-- 1 file changed, 83 insertions(+), 7 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index 3093b39175c..6e53e4d8614 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -145,6 +145,9 @@ public enum License { @Transient private String contributorNames; + + @Transient + private String jsonLd; @OneToMany(mappedBy="datasetVersion", cascade={CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST}) private List datasetVersionUsers; @@ -770,7 +773,57 @@ public List getDatasetSubjects() { } return subjects; } - + + /** + * @return List of Strings containing the version's Topic Classifications + */ + public List getTopicClassifications() { + List topicClassifications = new ArrayList<>(); + for (DatasetField dsf : this.getDatasetFields()) { + if (dsf.getDatasetFieldType().getName().equals(DatasetFieldConstant.topicClassification)) { + for (DatasetFieldCompoundValue topicClassValue : dsf.getDatasetFieldCompoundValues()) { + for (DatasetField subField : topicClassValue.getChildDatasetFields()) { + if (subField.getDatasetFieldType().getName().equals(DatasetFieldConstant.topicClassValue)) { + String topic = subField.getValue(); + // Field values should NOT be empty or, especially, null + // - in the ideal world. But as we are realizing, they CAN + // be null in real life databases. So, a check, just in case: + if (!StringUtil.isEmpty(topic)) { + topicClassifications.add(subField.getValue()); + } + } + } + } + } + } + return topicClassifications; + } + + /** + * @return List of Strings containing the version's Keywords + */ + public List getKeywords() { + List keywords = new ArrayList<>(); + for (DatasetField dsf : this.getDatasetFields()) { + if (dsf.getDatasetFieldType().getName().equals(DatasetFieldConstant.keyword)) { + for (DatasetFieldCompoundValue keywordFieldValue : dsf.getDatasetFieldCompoundValues()) { + for (DatasetField subField : keywordFieldValue.getChildDatasetFields()) { + if (subField.getDatasetFieldType().getName().equals(DatasetFieldConstant.keywordValue)) { + String keyword = subField.getValue(); + // Field values should NOT be empty or, especially, null, + // - in the ideal world. But as we are realizing, they CAN + // be null in real life databases. So, a check, just in case: + if (!StringUtil.isEmpty(keyword)) { + keywords.add(subField.getValue()); + } + } + } + } + } + } + return keywords; + } + public String getDatasetProducersString(){ String retVal = ""; for (DatasetField dsf : this.getDatasetFields()) { @@ -1157,11 +1210,25 @@ public String getPublicationDateAsString() { } // TODO: Make this more performant by writing the output to the database or a file? + // Agree - now that this has grown into a somewhat complex chunk of formatted + // metadata - and not just a couple of values inserted into the page html - + // it feels like it would make more sense to treat it as another supported + // export format, that can be produced once and cached. + // The problem with that is that the export subsystem assumes there is only + // one metadata export in a given format per dataset (it uses the current + // released (published) version. This JSON fragment is generated for a + // specific released version - and we can have multiple released versions. + // So something will need to be modified to accommodate this. -- L.A. + public String getJsonLd() { // We show published datasets only for "datePublished" field below. if (!this.isPublished()) { return ""; } + + /*if (jsonLd != null) { + return jsonLd; + }*/ JsonObjectBuilder job = Json.createObjectBuilder(); job.add("@context", "http://schema.org"); job.add("@type", "Dataset"); @@ -1197,16 +1264,24 @@ public String getJsonLd() { job.add("dateModified", this.getPublicationDateAsString()); job.add("version", this.getVersionNumber().toString()); /** - * "keywords" - We are using getDatasetSubjects() for consistency with - * `meta name="DC.subject"` in the dataset "head" tag. Per #2243 in the - * future, we could consider adding datasetkeyword(s) and - * topicclassification(s) but we should keep it consistent with - * "DC.subject". + * "keywords" - contains subject(s), datasetkeyword(s) and topicclassification(s) + * metadata fields for the version. -- L.A. + * (see #2243 for details/discussion/feedback from Google) */ JsonArrayBuilder keywords = Json.createArrayBuilder(); + this.getDatasetSubjects().forEach((subjects) -> { keywords.add(subjects); }); + + this.getTopicClassifications().forEach((topics) -> { + keywords.add(topics); + }); + + this.getKeywords().forEach((keywordValues) -> { + keywords.add(keywordValues); + }); + job.add("keywords", keywords); /** @@ -1254,7 +1329,8 @@ public String getJsonLd() { .add("@type", "Organization") .add("name", "Dataverse") ); - return job.build().toString(); + jsonLd = job.build().toString(); + return jsonLd; } } From 67882ff7add249d340715f7f3b0ae364692ee1a0 Mon Sep 17 00:00:00 2001 From: Leonid Andreev Date: Wed, 15 Nov 2017 19:41:05 -0500 Subject: [PATCH 18/22] the ld json fragment should now be structured as specified in the issue #2243. --- .../harvard/iq/dataverse/DatasetVersion.java | 66 ++++++++++++------- .../iq/dataverse/util/SystemConfig.java | 4 ++ .../iq/dataverse/DatasetVersionTest.java | 4 +- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index 6e53e4d8614..33ab239e5a7 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -3,8 +3,10 @@ import edu.harvard.iq.dataverse.util.MarkupChecker; import edu.harvard.iq.dataverse.DatasetFieldType.FieldType; import edu.harvard.iq.dataverse.util.StringUtil; +import edu.harvard.iq.dataverse.util.SystemConfig; import edu.harvard.iq.dataverse.workflows.WorkflowComment; import java.io.Serializable; +import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -778,7 +780,7 @@ public List getDatasetSubjects() { * @return List of Strings containing the version's Topic Classifications */ public List getTopicClassifications() { - List topicClassifications = new ArrayList<>(); + List topics = new ArrayList<>(); for (DatasetField dsf : this.getDatasetFields()) { if (dsf.getDatasetFieldType().getName().equals(DatasetFieldConstant.topicClassification)) { for (DatasetFieldCompoundValue topicClassValue : dsf.getDatasetFieldCompoundValues()) { @@ -789,14 +791,14 @@ public List getTopicClassifications() { // - in the ideal world. But as we are realizing, they CAN // be null in real life databases. So, a check, just in case: if (!StringUtil.isEmpty(topic)) { - topicClassifications.add(subField.getValue()); + topics.add(subField.getValue()); } } } } } } - return topicClassifications; + return topics; } /** @@ -1226,13 +1228,13 @@ public String getJsonLd() { return ""; } - /*if (jsonLd != null) { + if (jsonLd != null) { return jsonLd; - }*/ + } JsonObjectBuilder job = Json.createObjectBuilder(); job.add("@context", "http://schema.org"); job.add("@type", "Dataset"); - job.add("@id", this.getDataset().getPersistentURL()); + job.add("@identifier", this.getDataset().getPersistentURL()); job.add("name", this.getTitle()); JsonArrayBuilder authors = Json.createArrayBuilder(); for (DatasetAuthor datasetAuthor : this.getDatasetAuthors()) { @@ -1263,6 +1265,7 @@ public String getJsonLd() { */ job.add("dateModified", this.getPublicationDateAsString()); job.add("version", this.getVersionNumber().toString()); + job.add("description", this.getDescriptionPlainText()); /** * "keywords" - contains subject(s), datasetkeyword(s) and topicclassification(s) * metadata fields for the version. -- L.A. @@ -1270,17 +1273,17 @@ public String getJsonLd() { */ JsonArrayBuilder keywords = Json.createArrayBuilder(); - this.getDatasetSubjects().forEach((subjects) -> { - keywords.add(subjects); - }); + for (String subject : this.getDatasetSubjects()) { + keywords.add(subject); + } - this.getTopicClassifications().forEach((topics) -> { - keywords.add(topics); - }); + for (String topic : this.getTopicClassifications()) { + keywords.add(topic); + } - this.getKeywords().forEach((keywordValues) -> { - keywords.add(keywordValues); - }); + for (String keyword : this.getKeywords()) { + keywords.add(keyword); + } job.add("keywords", keywords); @@ -1308,21 +1311,40 @@ public String getJsonLd() { } /** - * spatialCoverage: - * (if available) + * spatialCoverage (if available) * TODO + * (punted, for now - see #2243) + * */ /** - * "funder": + * funder (if available) * TODO - * (see 2243 for info on how to format -- L.A.) - */ + * (punted, for now - see #2243) + */ job.add("schemaVersion", "https://schema.org/version/3.3"); - job.add("publisher", Json.createObjectBuilder() - .add("@type", "Organization") + + TermsOfUseAndAccess terms = this.getTermsOfUseAndAccess(); + if (terms != null) { + if (TermsOfUseAndAccess.License.CC0.equals(terms.getLicense())) { + job.add("license", Json.createObjectBuilder() + .add("@type", "Dataset") + .add("text", "CC0") + .add("url", "https://creativecommons.org/publicdomain/zero/1.0/") + ); + + } else { + job.add("license", Json.createObjectBuilder() + .add("text", terms.getTermsOfUse()) + ); + } + } + + job.add("includedInDataCatalog", Json.createObjectBuilder() + .add("@type", "DataCatalog") .add("name", this.getRootDataverseNameforCitation()) + .add("url", SystemConfig.getDataverseSiteUrlStatic()) ); job.add("provider", Json.createObjectBuilder() diff --git a/src/main/java/edu/harvard/iq/dataverse/util/SystemConfig.java b/src/main/java/edu/harvard/iq/dataverse/util/SystemConfig.java index ee26d1e19c5..76f3bc31c65 100644 --- a/src/main/java/edu/harvard/iq/dataverse/util/SystemConfig.java +++ b/src/main/java/edu/harvard/iq/dataverse/util/SystemConfig.java @@ -275,6 +275,10 @@ public static int getMinutesUntilPasswordResetTokenExpires() { * by the Settings Service configuration. */ public String getDataverseSiteUrl() { + return getDataverseSiteUrlStatic(); + } + + public static String getDataverseSiteUrlStatic() { String hostUrl = System.getProperty(SITE_URL); if (hostUrl != null && !"".equals(hostUrl)) { return hostUrl; diff --git a/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java b/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java index 12550f14665..3c52cb2af0b 100644 --- a/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java @@ -121,7 +121,7 @@ public void testGetJsonLd() throws ParseException { JsonObject obj = jsonReader.readObject(); assertEquals("http://schema.org", obj.getString("@context")); assertEquals("Dataset", obj.getString("@type")); - assertEquals("http://dx.doi.org/10.5072/FK2/LK0D1H", obj.getString("@id")); + assertEquals("http://dx.doi.org/10.5072/FK2/LK0D1H", obj.getString("@identifier")); assertEquals("https://schema.org/version/3.3", obj.getString("schemaVersion")); assertEquals("1955-11-05", obj.getString("dateModified")); assertEquals("1955-11-05", obj.getString("datePublished")); @@ -134,7 +134,7 @@ public void testGetJsonLd() throws ParseException { // TODO: If it ever becomes easier to mock subjects, test them. assertEquals(emptyArray, obj.getJsonArray("keywords")); assertEquals("Dataverse", obj.getJsonObject("provider").getString("name")); - assertEquals("LibraScholar", obj.getJsonObject("publisher").getString("name")); + assertEquals("LibraScholar", obj.getJsonObject("includedInDataCatalog").getString("name")); assertEquals(datasetVersion.getCitation(), obj.getJsonObject("citation").getString("text")); } From e0399c1cc274e0294563c071a204bbf2242de9a5 Mon Sep 17 00:00:00 2001 From: Leonid Andreev Date: Wed, 15 Nov 2017 19:50:54 -0500 Subject: [PATCH 19/22] ...and a quick fix for the "temporalCoverage" entry (#2243) --- src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index 33ab239e5a7..46829c38b12 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -731,14 +731,17 @@ public List getTimePeriodsCovered() { if (subField.isEmptyForDisplay()) { start = null; } else { - start = subField.getDisplayValue(); + // we want to use "getValue()", as opposed to "getDisplayValue()" here - + // as the latter method prepends the value with the word "Start:"! + start = subField.getValue(); } } if (subField.getDatasetFieldType().getName().equals(DatasetFieldConstant.timePeriodCoveredEnd)) { if (subField.isEmptyForDisplay()) { end = null; } else { - end = subField.getDisplayValue(); + // see the comment above + end = subField.getValue(); } } From a2742c53c642e009b65620b10bf3a51873e21dc8 Mon Sep 17 00:00:00 2001 From: Leonid Andreev Date: Fri, 17 Nov 2017 15:08:40 -0500 Subject: [PATCH 20/22] latest changest to ld json formatting, making the fragment pass the google validation tool test. (#2243) --- .../harvard/iq/dataverse/DatasetVersion.java | 86 ++++++++++--------- .../iq/dataverse/DatasetVersionTest.java | 3 +- 2 files changed, 46 insertions(+), 43 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index 46829c38b12..a2dc38428be 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -783,37 +783,35 @@ public List getDatasetSubjects() { * @return List of Strings containing the version's Topic Classifications */ public List getTopicClassifications() { - List topics = new ArrayList<>(); - for (DatasetField dsf : this.getDatasetFields()) { - if (dsf.getDatasetFieldType().getName().equals(DatasetFieldConstant.topicClassification)) { - for (DatasetFieldCompoundValue topicClassValue : dsf.getDatasetFieldCompoundValues()) { - for (DatasetField subField : topicClassValue.getChildDatasetFields()) { - if (subField.getDatasetFieldType().getName().equals(DatasetFieldConstant.topicClassValue)) { - String topic = subField.getValue(); - // Field values should NOT be empty or, especially, null - // - in the ideal world. But as we are realizing, they CAN - // be null in real life databases. So, a check, just in case: - if (!StringUtil.isEmpty(topic)) { - topics.add(subField.getValue()); - } - } - } - } - } - } - return topics; + return getCompoundChildFieldValues(DatasetFieldConstant.topicClassification, DatasetFieldConstant.topicClassValue); } - + /** * @return List of Strings containing the version's Keywords */ public List getKeywords() { + return getCompoundChildFieldValues(DatasetFieldConstant.keyword, DatasetFieldConstant.keywordValue); + } + + /** + * @return List of Strings containing the version's PublicationCitations + */ + public List getPublicationCitationValues() { + return getCompoundChildFieldValues(DatasetFieldConstant.publication, DatasetFieldConstant.publicationCitation); + } + + /** + * @param parentFieldName compound dataset field A (from DatasetFieldConstant.*) + * @param childFieldName dataset field B, child field of A (from DatasetFieldConstant.*) + * @return List of values of the child field + */ + public List getCompoundChildFieldValues(String parentFieldName, String childFieldName) { List keywords = new ArrayList<>(); for (DatasetField dsf : this.getDatasetFields()) { - if (dsf.getDatasetFieldType().getName().equals(DatasetFieldConstant.keyword)) { + if (dsf.getDatasetFieldType().getName().equals(parentFieldName)) { for (DatasetFieldCompoundValue keywordFieldValue : dsf.getDatasetFieldCompoundValues()) { for (DatasetField subField : keywordFieldValue.getChildDatasetFields()) { - if (subField.getDatasetFieldType().getName().equals(DatasetFieldConstant.keywordValue)) { + if (subField.getDatasetFieldType().getName().equals(childFieldName)) { String keyword = subField.getValue(); // Field values should NOT be empty or, especially, null, // - in the ideal world. But as we are realizing, they CAN @@ -1237,15 +1235,19 @@ public String getJsonLd() { JsonObjectBuilder job = Json.createObjectBuilder(); job.add("@context", "http://schema.org"); job.add("@type", "Dataset"); - job.add("@identifier", this.getDataset().getPersistentURL()); + job.add("identifier", this.getDataset().getPersistentURL()); job.add("name", this.getTitle()); JsonArrayBuilder authors = Json.createArrayBuilder(); for (DatasetAuthor datasetAuthor : this.getDatasetAuthors()) { JsonObjectBuilder author = Json.createObjectBuilder(); - String personOrOrganization = datasetAuthor.getName().getValue(); - String name = personOrOrganization; + String name = datasetAuthor.getName().getValue(); + String affiliation = datasetAuthor.getAffiliation().getValue(); // We are aware of "givenName" and "familyName" but instead of a person it might be an organization such as "Gallup Organization". + author.add("@type", "Person"); author.add("name", name); + if (!StringUtil.isEmpty(affiliation)) { + author.add("affiliation", affiliation); + } authors.add(author); } job.add("author", authors); @@ -1253,8 +1255,6 @@ public String getJsonLd() { * We are aware that there is a "datePublished" field but it means "Date * of first broadcast/publication." This only makes sense for a 1.0 * version. - * (Per @jggautier's comment 03/11/2017 in #2243, we are putting datePublished - * back -- L.A.) */ String datePublished = this.getDataset().getPublicationDateFormattedYYYYMMDD(); if (datePublished != null) { @@ -1292,12 +1292,19 @@ public String getJsonLd() { /** * citation: + * (multiple) publicationCitation values, if present: */ - JsonObjectBuilder citation = Json.createObjectBuilder(); - citation.add("@type", "Dataset"); - citation.add("text", this.getCitation()); - job.add("citation", citation); - /* should we use the HTML-style citation, i.e. this.getCitation(true) instead -- L.A.?) */ + + List publicationCitations = getPublicationCitationValues(); + if (publicationCitations.size() > 0) { + JsonArrayBuilder citation = Json.createArrayBuilder(); + for (String pubCitation : publicationCitations) { + //citationEntry.add("@type", "Dataset"); + //citationEntry.add("text", pubCitation); + citation.add(pubCitation); + } + job.add("citation", citation); + } /** * temporalCoverage: @@ -1330,18 +1337,15 @@ public String getJsonLd() { TermsOfUseAndAccess terms = this.getTermsOfUseAndAccess(); if (terms != null) { + JsonObjectBuilder license = Json.createObjectBuilder().add("@type", "Dataset"); + if (TermsOfUseAndAccess.License.CC0.equals(terms.getLicense())) { - job.add("license", Json.createObjectBuilder() - .add("@type", "Dataset") - .add("text", "CC0") - .add("url", "https://creativecommons.org/publicdomain/zero/1.0/") - ); - + license.add("text", "CC0").add("url", "https://creativecommons.org/publicdomain/zero/1.0/"); } else { - job.add("license", Json.createObjectBuilder() - .add("text", terms.getTermsOfUse()) - ); + license.add("text", terms.getTermsOfUse()); } + + job.add("license",license); } job.add("includedInDataCatalog", Json.createObjectBuilder() diff --git a/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java b/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java index 3c52cb2af0b..2429c288d55 100644 --- a/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/DatasetVersionTest.java @@ -121,7 +121,7 @@ public void testGetJsonLd() throws ParseException { JsonObject obj = jsonReader.readObject(); assertEquals("http://schema.org", obj.getString("@context")); assertEquals("Dataset", obj.getString("@type")); - assertEquals("http://dx.doi.org/10.5072/FK2/LK0D1H", obj.getString("@identifier")); + assertEquals("http://dx.doi.org/10.5072/FK2/LK0D1H", obj.getString("identifier")); assertEquals("https://schema.org/version/3.3", obj.getString("schemaVersion")); assertEquals("1955-11-05", obj.getString("dateModified")); assertEquals("1955-11-05", obj.getString("datePublished")); @@ -135,7 +135,6 @@ public void testGetJsonLd() throws ParseException { assertEquals(emptyArray, obj.getJsonArray("keywords")); assertEquals("Dataverse", obj.getJsonObject("provider").getString("name")); assertEquals("LibraScholar", obj.getJsonObject("includedInDataCatalog").getString("name")); - assertEquals(datasetVersion.getCitation(), obj.getJsonObject("citation").getString("text")); } } From 0801d56fd07db8967f479d04d7ddeef5a2a18c4e Mon Sep 17 00:00:00 2001 From: Leonid Andreev Date: Fri, 17 Nov 2017 15:36:04 -0500 Subject: [PATCH 21/22] ldjson should will only be embedded into the page if this is the LATEST PUBLISHED version (#2243) --- .../edu/harvard/iq/dataverse/DatasetPage.java | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 64d0012d4b9..45ecf178c52 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -79,6 +79,7 @@ import java.util.logging.Level; import edu.harvard.iq.dataverse.datasetutility.TwoRavensHelper; import edu.harvard.iq.dataverse.datasetutility.WorldMapPermissionHelper; +import edu.harvard.iq.dataverse.engine.command.impl.GetLatestPublishedDatasetVersionCommand; import edu.harvard.iq.dataverse.engine.command.impl.RequestRsyncScriptCommand; import edu.harvard.iq.dataverse.engine.command.impl.PublishDatasetResult; import edu.harvard.iq.dataverse.engine.command.impl.RestrictFileCommand; @@ -3957,8 +3958,37 @@ public List getDatasetSummaryFields() { return DatasetUtil.getDatasetSummaryFields(workingVersion, customFields); } - + + Boolean thisLatestReleasedVersion = null; + + public boolean isThisLatestReleasedVersion() { + if (thisLatestReleasedVersion != null) { + return thisLatestReleasedVersion; + } + + if (!workingVersion.isPublished()) { + thisLatestReleasedVersion = false; + return false; + } + + DatasetVersion latestPublishedVersion = null; + Command cmd = new GetLatestPublishedDatasetVersionCommand(dvRequestService.getDataverseRequest(), dataset); + try { + latestPublishedVersion = commandEngine.submit(cmd); + } catch (Exception ex) { + // whatever... + } + + thisLatestReleasedVersion = workingVersion.equals(latestPublishedVersion); + + return thisLatestReleasedVersion; + + } + public String getJsonLd() { - return workingVersion.getJsonLd(); + if (isThisLatestReleasedVersion()) { + return workingVersion.getJsonLd(); + } + return ""; } } From eec1163fdf60b1fb44c6c635840fd2e1ba22f9ea Mon Sep 17 00:00:00 2001 From: Leonid Andreev Date: Fri, 17 Nov 2017 15:58:38 -0500 Subject: [PATCH 22/22] Per conversation with jgautier stipped the '@type="person"' attribute in the author fragment; since it can be a person or an organization; this results in a warning from google validation tool (because "Thing" is not supposed to have an affiliation) but it appears to be ok to live with it. --- src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index a2dc38428be..d8eacf4bbfb 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -1243,7 +1243,7 @@ public String getJsonLd() { String name = datasetAuthor.getName().getValue(); String affiliation = datasetAuthor.getAffiliation().getValue(); // We are aware of "givenName" and "familyName" but instead of a person it might be an organization such as "Gallup Organization". - author.add("@type", "Person"); + //author.add("@type", "Person"); author.add("name", name); if (!StringUtil.isEmpty(affiliation)) { author.add("affiliation", affiliation);