Skip to content

Commit

Permalink
Merge tag 'v5.14-DANS-DataStation-PATCH-4' of github.com:DANS-KNAW/da…
Browse files Browse the repository at this point in the history
…taverse into AddPatch4ToDVNL
  • Loading branch information
PaulBoon committed Oct 12, 2023
2 parents 2c0a92d + 2b5c243 commit 555c3e8
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 68 deletions.
1 change: 1 addition & 0 deletions doc/release-notes/9955-Signposting-updates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This release fixes two issues (#9952, #9953) where the Signposting output did not match the Signposting specification.
9 changes: 9 additions & 0 deletions doc/release-notes/9983-unique-constraints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
This release adds two missing database constraints that will assure that the externalvocabularyvalue table only has one entry for each uri and that the oaiset table only has one set for each spec. (In the very unlikely case that your existing database has duplicate entries now, install would fail. This can be checked by running

SELECT uri, count(*) FROM externalvocabularyvaluet group by uri;

and

SELECT spec, count(*) FROM oaiset group by spec;

and then removing any duplicate rows (where count>1).
4 changes: 2 additions & 2 deletions doc/sphinx-guides/source/api/native-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2171,11 +2171,11 @@ Signposting involves the addition of a `Link <https://tools.ietf.org/html/rfc598

Here is an example of a "Link" header:

``Link: <https://doi.org/10.5072/FK2/YD5QDG>;rel="cite-as", <https://doi.org/10.5072/FK2/YD5QDG>;rel="describedby";type="application/vnd.citationstyles.csl+json",<https://demo.dataverse.org/api/datasets/export?exporter=schema.org&persistentId=doi:10.5072/FK2/YD5QDG>;rel="describedby";type="application/json+ld", <https://schema.org/AboutPage>;rel="type",<https://schema.org/Dataset>;rel="type", https://demo.dataverse.org/api/datasets/:persistentId/versions/1.0/customlicense?persistentId=doi:10.5072/FK2/YD5QDG;rel="license", <https://demo.dataverse.org/api/datasets/:persistentId/versions/1.0/linkset?persistentId=doi:10.5072/FK2/YD5QDG> ; rel="linkset";type="application/linkset+json"``
``Link: <https://doi.org/10.5072/FK2/YD5QDG>;rel="cite-as", <https://doi.org/10.5072/FK2/YD5QDG>;rel="describedby";type="application/vnd.citationstyles.csl+json",<https://demo.dataverse.org/api/datasets/export?exporter=schema.org&persistentId=doi:10.5072/FK2/YD5QDG>;rel="describedby";type="application/ld+json", <https://schema.org/AboutPage>;rel="type",<https://schema.org/Dataset>;rel="type", <https://demo.dataverse.org/api/datasets/:persistentId/versions/1.0/customlicense?persistentId=doi:10.5072/FK2/YD5QDG>;rel="license", <https://demo.dataverse.org/api/datasets/:persistentId/versions/1.0/linkset?persistentId=doi:10.5072/FK2/YD5QDG> ; rel="linkset";type="application/linkset+json"``

The URL for linkset information is discoverable under the ``rel="linkset";type="application/linkset+json`` entry in the "Link" header, such as in the example above.

The reponse includes a JSON object conforming to the `Signposting <https://signposting.org>`__ specification.
The reponse includes a JSON object conforming to the `Signposting <https://signposting.org>`__ specification. As part of this conformance, unlike most Dataverse API responses, the output is not wrapped in a ``{"status":"OK","data":{`` object.
Signposting is not supported for draft dataset versions.

.. code-block:: bash
Expand Down
87 changes: 47 additions & 40 deletions src/main/java/edu/harvard/iq/dataverse/DatasetFieldServiceBean.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ public void setDisplayOnCreate(boolean displayOnCreate) {
}

public boolean isControlledVocabulary() {
return controlledVocabularyValues != null && !controlledVocabularyValues.isEmpty();
return allowControlledVocabulary;
}

/**
Expand Down
18 changes: 13 additions & 5 deletions src/main/java/edu/harvard/iq/dataverse/DatasetPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -2864,6 +2864,12 @@ public void sort() {
public String refresh() {
logger.fine("refreshing");

//In v5.14, versionId was null here. In 6.0, it appears not to be.
//This check is to handle the null if it reappears/occurs under other circumstances
if(versionId==null) {
logger.warning("versionId was null in refresh");
versionId = workingVersion.getId();
}
//dataset = datasetService.find(dataset.getId());
dataset = null;
workingVersion = null;
Expand All @@ -2873,10 +2879,9 @@ public String refresh() {
DatasetVersionServiceBean.RetrieveDatasetVersionResponse retrieveDatasetVersionResponse = null;

if (versionId != null) {
// versionId must have been set by now, in the init() method,
// regardless of how the page was originally called - by the dataset
// database id, by the persistent identifier, or by the db id of
// the version.
// versionId must have been set by now (see null check above), in the init()
// method, regardless of how the page was originally called - by the dataset
// database id, by the persistent identifier, or by the db id of the version.
this.workingVersion = datasetVersionService.findDeep(versionId);
dataset = workingVersion.getDataset();
}
Expand Down Expand Up @@ -6145,7 +6150,10 @@ public String getWebloaderUrlForDataset(Dataset d) {
String signpostingLinkHeader = null;

public String getSignpostingLinkHeader() {
if (!workingVersion.isReleased()) {
if ((workingVersion==null) || (!workingVersion.isReleased())) {
if(workingVersion==null) {
logger.warning("workingVersion was null in getSignpostingLinkHeader");
}
return null;
}
if (signpostingLinkHeader == null) {
Expand Down
34 changes: 18 additions & 16 deletions src/main/java/edu/harvard/iq/dataverse/api/Datasets.java
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ public Response getDataset(@Context ContainerRequestContext crc, @PathParam("id"

@GET
@Path("/export")
@Produces({"application/xml", "application/json", "application/html" })
@Produces({"application/xml", "application/json", "application/html", "application/ld+json" })
public Response exportDataset(@QueryParam("persistentId") String persistentId, @QueryParam("exporter") String exporter, @Context UriInfo uriInfo, @Context HttpHeaders headers, @Context HttpServletResponse response) {

try {
Expand Down Expand Up @@ -579,24 +579,26 @@ public Response getVersionMetadataBlock(@Context ContainerRequestContext crc,
@GET
@AuthRequired
@Path("{id}/versions/{versionId}/linkset")
public Response getLinkset(@Context ContainerRequestContext crc, @PathParam("id") String datasetId, @PathParam("versionId") String versionId, @Context UriInfo uriInfo, @Context HttpHeaders headers) {
if ( ":draft".equals(versionId) ) {
public Response getLinkset(@Context ContainerRequestContext crc, @PathParam("id") String datasetId, @PathParam("versionId") String versionId,
@Context UriInfo uriInfo, @Context HttpHeaders headers) {
if (":draft".equals(versionId)) {
return badRequest("Signposting is not supported on the :draft version");
}
User user = getRequestUser(crc);
return response(req -> {
DataverseRequest req = createDataverseRequest(getRequestUser(crc));
try {
DatasetVersion dsv = getDatasetVersionOrDie(req, versionId, findDatasetOrDie(datasetId), uriInfo, headers);
return ok(Json.createObjectBuilder().add(
"linkset",
new SignpostingResources(
systemConfig,
dsv,
JvmSettings.SIGNPOSTING_LEVEL1_AUTHOR_LIMIT.lookupOptional().orElse(""),
JvmSettings.SIGNPOSTING_LEVEL1_ITEM_LIMIT.lookupOptional().orElse("")
).getJsonLinkset()
)
);
}, user);
return Response
.ok(Json.createObjectBuilder()
.add("linkset",
new SignpostingResources(systemConfig, dsv,
JvmSettings.SIGNPOSTING_LEVEL1_AUTHOR_LIMIT.lookupOptional().orElse(""),
JvmSettings.SIGNPOSTING_LEVEL1_ITEM_LIMIT.lookupOptional().orElse(""))
.getJsonLinkset())
.build())
.type(MediaType.APPLICATION_JSON).build();
} catch (WrappedResponse wr) {
return wr.getResponse();
}
}

@GET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,14 @@ public String getLinks() {

String describedby = "<" + ds.getGlobalId().asURL().toString() + ">;rel=\"describedby\"" + ";type=\"" + "application/vnd.citationstyles.csl+json\"";
describedby += ",<" + systemConfig.getDataverseSiteUrl() + "/api/datasets/export?exporter=schema.org&persistentId="
+ ds.getProtocol() + ":" + ds.getAuthority() + "/" + ds.getIdentifier() + ">;rel=\"describedby\"" + ";type=\"application/json+ld\"";
+ ds.getProtocol() + ":" + ds.getAuthority() + "/" + ds.getIdentifier() + ">;rel=\"describedby\"" + ";type=\"application/ld+json\"";
valueList.add(describedby);

String type = "<https://schema.org/AboutPage>;rel=\"type\"";
type = "<https://schema.org/AboutPage>;rel=\"type\",<" + defaultFileTypeValue + ">;rel=\"type\"";
valueList.add(type);

String licenseString = DatasetUtil.getLicenseURI(workingDatasetVersion) + ";rel=\"license\"";
String licenseString = "<" + DatasetUtil.getLicenseURI(workingDatasetVersion) + ">;rel=\"license\"";
valueList.add(licenseString);

String linkset = "<" + systemConfig.getDataverseSiteUrl() + "/api/datasets/:persistentId/versions/"
Expand Down Expand Up @@ -116,7 +116,7 @@ public JsonArrayBuilder getJsonLinkset() {
systemConfig.getDataverseSiteUrl() + "/api/datasets/export?exporter=schema.org&persistentId=" + ds.getProtocol() + ":" + ds.getAuthority() + "/" + ds.getIdentifier()
).add(
"type",
"application/json+ld"
"application/ld+json"
)
);
JsonArrayBuilder linksetJsonObj = Json.createArrayBuilder();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
DO $$
BEGIN

BEGIN
ALTER TABLE externalvocabularyvalue ADD CONSTRAINT externalvocabularvalue_uri_key UNIQUE(uri);
EXCEPTION
WHEN duplicate_table THEN RAISE NOTICE 'Table unique constraint externalvocabularvalue_uri_key already exists';
END;

BEGIN
ALTER TABLE oaiset ADD CONSTRAINT oaiset_spec_key UNIQUE(spec);
EXCEPTION
WHEN duplicate_table THEN RAISE NOTICE 'Table unique constraint oaiset_spec_key already exists';
END;

END $$;
13 changes: 12 additions & 1 deletion src/test/java/edu/harvard/iq/dataverse/api/SignpostingIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public void testSignposting() {
assertTrue(linkHeader.contains(datasetPid));
assertTrue(linkHeader.contains("cite-as"));
assertTrue(linkHeader.contains("describedby"));
assertTrue(linkHeader.contains("<http://creativecommons.org/publicdomain/zero/1.0>;rel=\"license\""));

Pattern pattern = Pattern.compile("<([^<]*)> ; rel=\"linkset\";type=\"application\\/linkset\\+json\"");
Matcher matcher = pattern.matcher(linkHeader);
Expand All @@ -92,7 +93,7 @@ public void testSignposting() {

String responseString = linksetResponse.getBody().asString();

JsonObject data = JsonUtil.getJsonObject(responseString).getJsonObject("data");
JsonObject data = JsonUtil.getJsonObject(responseString);
JsonObject lso = data.getJsonArray("linkset").getJsonObject(0);
System.out.println("Linkset: " + lso.toString());

Expand All @@ -101,6 +102,16 @@ public void testSignposting() {
assertTrue(lso.getString("anchor").indexOf("/dataset.xhtml?persistentId=" + datasetPid) > 0);
assertTrue(lso.containsKey("describedby"));

// Test export URL from link header
// regex inspired by https://stackoverflow.com/questions/68860255/how-to-match-the-closest-opening-and-closing-brackets
Pattern exporterPattern = Pattern.compile("[<\\[][^()\\[\\]]*?exporter=schema.org[^()\\[\\]]*[>\\]]");
Matcher exporterMatcher = exporterPattern.matcher(linkHeader);
exporterMatcher.find();

Response exportDataset = UtilIT.exportDataset(datasetPid, "schema.org");
exportDataset.prettyPrint();
exportDataset.then().assertThat().statusCode(OK.getStatusCode());

}

}

0 comments on commit 555c3e8

Please sign in to comment.