Skip to content

Commit

Permalink
Merge pull request #8558 from IQSS/8551-sword-license
Browse files Browse the repository at this point in the history
remove NONE as a license option for SWORD, show available licenses #8551
  • Loading branch information
kcondon authored Apr 5, 2022
2 parents 8c70b7a + fa9ac6e commit 1541391
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 8 deletions.
1 change: 1 addition & 0 deletions doc/release-notes/8551-sword-license.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
As of Dataverse 5.10, "NONE" is no longer supported as a valid license when creating a dataset using the SWORD API. The API Guide has been updated to reflect this. Additionally, if you specify an invalid license, a list of available licenses will be returned in the response.
4 changes: 2 additions & 2 deletions doc/sphinx-guides/source/api/sword-atom-entry.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
<dcterms:coverage>United States</dcterms:coverage>
<dcterms:coverage>Canada</dcterms:coverage>
<!-- license and restrictions -->
<dcterms:license>NONE</dcterms:license>
<dcterms:rights>Downloader will not use the Materials in any way prohibited by applicable laws.</dcterms:rights>
<dcterms:license>CC0 1.0</dcterms:license>
<!--<dcterms:rights>Downloader will not use the Materials in any way prohibited by applicable laws.</dcterms:rights>-->
<!-- related publications -->
<dcterms:isReferencedBy holdingsURI="http://dx.doi.org/10.1038/dvn333" agency="DOI" IDNo="10.1038/dvn333">Peets, J., &amp; Stumptown, J. (2013). Roasting at Home. New England Journal of Coffee, 3(1), 22-34.</dcterms:isReferencedBy>
</entry>
8 changes: 5 additions & 3 deletions doc/sphinx-guides/source/api/sword.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ Differences in Dataverse Software 4 from DVN 3.x lead to a few minor backward in

- The Service Document will show a single API Terms of Use rather than root level and Dataverse collection level Deposit Terms of Use.

- As of Dataverse Software 5.10, ``NONE`` is no longer supported as a license.

New features as of v1.1
-----------------------

Expand All @@ -80,7 +82,7 @@ New features as of v1.1

- "Contributor" can now be populated and the "Type" (Editor, Funder, Researcher, etc.) can be specified with an XML attribute. For example: ``<dcterms:contributor type="Funder">CaffeineForAll</dcterms:contributor>``

- "License" can now be set with ``dcterms:license`` and the possible values are "CC0" and "NONE". "License" interacts with "Terms of Use" (``dcterms:rights``) in that if you include ``dcterms:rights`` in the XML, the license will be set to "NONE". If you don't include ``dcterms:rights``, the license will default to "CC0". It is invalid to specify "CC0" as a license and also include ``dcterms:rights``; an error will be returned. For backwards compatibility, ``dcterms:rights`` is allowed to be blank (i.e. ``<dcterms:rights></dcterms:rights>``) but blank values will not be persisted to the database and the license will be set to "NONE".
- "License" can now be set with ``dcterms:license`` and the possible values determined by the installation ("CC0 1.0" and "CC BY 4.0" by default). "License" interacts with "Terms of Use" (``dcterms:rights``) in that if you include ``dcterms:rights`` in the XML and don't include ``dcterms:license``, the license will be "Custom Dataset Terms" and "Terms of Use" will be populated. If you don't include ``dcterms:rights``, the default license will be used. It is invalid to specify a license and also include ``dcterms:rights``; an error will be returned. For backwards compatibility, ``dcterms:rights`` is allowed to be blank (i.e. ``<dcterms:rights></dcterms:rights>``) but blank values will not be persisted to the database and the license will be set to "Custom Dataset Terms".

- "Contact E-mail" is automatically populated from dataset owner's email.

Expand Down Expand Up @@ -143,9 +145,9 @@ Dublin Core Terms (DC Terms) Qualified Mapping - Dataverse Project DB Element Cr
+-----------------------------+----------------------------------------------+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
|dcterms:coverage | otherGeographicCoverage | | General information on the geographic coverage of the Dataset. |
+-----------------------------+----------------------------------------------+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
|dcterms:license | license | | Set the license to CC0 (default in a Dataverse installation for new Datasets), otherwise enter "NONE" and fill in the dcterms:rights field. |
|dcterms:license | license | | Set the license. Alternatively, use the dcterms:rights field instead. |
+-----------------------------+----------------------------------------------+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
|dcterms:rights | termsofuse | | If not using CC0, enter any terms of use or restrictions for the Dataset. |
|dcterms:rights | termsofuse | | If not using dcterms:license, enter any terms of use or restrictions for the Dataset. |
+-----------------------------+----------------------------------------------+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
|dcterms:isReferencedBy | publicationCitation | | The publication (journal article, book, other work) that uses this dataset (include citation, permanent identifier (DOI), and permanent URL). |
+-----------------------------+----------------------------------------------+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import edu.harvard.iq.dataverse.license.License;
import edu.harvard.iq.dataverse.license.LicenseServiceBean;
import edu.harvard.iq.dataverse.util.BundleUtil;
import java.util.ArrayList;

import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -186,7 +187,13 @@ public void setDatasetLicenseAndTermsOfUse(DatasetVersion datasetVersionToMutate
setTermsOfUse(datasetVersionToMutate, dcterms, null);
} else {
License licenseToSet = licenseServiceBean.getByNameOrUri(licenseProvided);
if (licenseToSet == null) throw new SwordError("Couldn't find an active license with: " + licenseProvided);
if (licenseToSet == null || !licenseToSet.isActive()) {
List<String> licenses = new ArrayList<>();
for (License license : licenseServiceBean.listAllActive()) {
licenses.add(license.getName());
}
throw new SwordError("Couldn't find an active license with: " + licenseProvided + ". Valid licenses: " + licenses);
}
terms.setLicense(licenseToSet);
setTermsOfUse(datasetVersionToMutate, dcterms, licenseToSet);
}
Expand All @@ -204,7 +211,7 @@ private void setTermsOfUse(DatasetVersion datasetVersionToMutate, Map<String, Li
int numRightsProvided = listOfRightsProvided.size();
if (providedLicense != null) {
if (numRightsProvided > 0) {
throw new SwordError("Terms of Use (dcterms:rights) can not be specified in combination with a license. A Custom License can be used instead.");
throw new SwordError("Terms of Use (dcterms:rights) cannot be specified in combination with a license.");
}
} else {
if (numRightsProvided != 1) {
Expand Down
111 changes: 111 additions & 0 deletions src/test/java/edu/harvard/iq/dataverse/api/SwordIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import com.jayway.restassured.response.Response;
import edu.harvard.iq.dataverse.GlobalId;
import edu.harvard.iq.dataverse.api.datadeposit.SwordConfigurationImpl;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;

import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -195,6 +198,13 @@ public void testCreateDataverseCreateDatasetUploadFileDownloadFileEditTitle() {
String persistentId = UtilIT.getDatasetPersistentIdFromSwordResponse(createDatasetResponse);
logger.info("persistent id: " + persistentId);

Response getJson = UtilIT.nativeGetUsingPersistentId(persistentId, apiToken);
getJson.prettyPrint();
getJson.then().assertThat()
.statusCode(OK.getStatusCode())
.body("data.latestVersion.license.name", equalTo("CC0 1.0"))
.body("data.latestVersion.license.uri", equalTo("http://creativecommons.org/publicdomain/zero/1.0"));

Response atomEntryUnAuth = UtilIT.getSwordAtomEntry(persistentId, apiTokenNoPrivs);
atomEntryUnAuth.prettyPrint();
atomEntryUnAuth.then().assertThat()
Expand Down Expand Up @@ -638,6 +648,107 @@ public void testCreateDatasetPublishDestroy() {

}


@Test
public void testLicenses() {

Response createUser = UtilIT.createRandomUser();
String username = UtilIT.getUsernameFromResponse(createUser);
String apiToken = UtilIT.getApiTokenFromResponse(createUser);

Response createDataverse = UtilIT.createRandomDataverse(apiToken);
createDataverse.prettyPrint();
createDataverse.then().assertThat()
.statusCode(CREATED.getStatusCode());
String dataverseAlias = UtilIT.getAliasFromResponse(createDataverse);

String title = "License to Kill";
String description = "Spies in 1989";
String license = "NONE";
Response failToCreateDataset1 = UtilIT.createDatasetViaSwordApi(dataverseAlias, title, description, license, apiToken);
failToCreateDataset1.prettyPrint();
// As of 5.10 and PR #7920, you cannot pass NONE as a license.
failToCreateDataset1.then().assertThat()
.statusCode(BAD_REQUEST.getStatusCode());

String rights = "Call me";
Response failToCreateDataset2 = UtilIT.createDatasetViaSwordApi(dataverseAlias, title, description, license, rights, apiToken);
failToCreateDataset2.prettyPrint();
// You can't pass both license and rights
failToCreateDataset2.then().assertThat()
.statusCode(BAD_REQUEST.getStatusCode());

license = "CC0 1.0";
Response createDataset = UtilIT.createDatasetViaSwordApi(dataverseAlias, title, description, license, apiToken);
createDataset.prettyPrint();
createDataset.then().assertThat()
.statusCode(CREATED.getStatusCode());

String persistentId = UtilIT.getDatasetPersistentIdFromSwordResponse(createDataset);

Response getJson = UtilIT.nativeGetUsingPersistentId(persistentId, apiToken);
getJson.prettyPrint();
getJson.then().assertThat()
.statusCode(OK.getStatusCode())
.body("data.latestVersion.license.name", equalTo("CC0 1.0"))
.body("data.latestVersion.license.uri", equalTo("http://creativecommons.org/publicdomain/zero/1.0"))
.body("data.latestVersion.termsOfUse", equalTo(null));
}

@Test
public void testCustomTerms() {

Response createUser = UtilIT.createRandomUser();
String username = UtilIT.getUsernameFromResponse(createUser);
String apiToken = UtilIT.getApiTokenFromResponse(createUser);

Response createDataverse = UtilIT.createRandomDataverse(apiToken);
createDataverse.prettyPrint();
createDataverse.then().assertThat()
.statusCode(CREATED.getStatusCode());
String dataverseAlias = UtilIT.getAliasFromResponse(createDataverse);

String title = "Terms of Endearment";
String description = "Aurora, etc.";
String license = null;
String rights = "Call me";
Response createDataset = UtilIT.createDatasetViaSwordApi(dataverseAlias, title, description, license, rights, apiToken);
createDataset.prettyPrint();
createDataset.then().assertThat()
.statusCode(CREATED.getStatusCode());

String persistentId = UtilIT.getDatasetPersistentIdFromSwordResponse(createDataset);

Response getJson = UtilIT.nativeGetUsingPersistentId(persistentId, apiToken);
getJson.prettyPrint();
getJson.then().assertThat()
.statusCode(OK.getStatusCode())
.body("data.latestVersion.termsOfUse", equalTo("Call me"))
.body("data.latestVersion.license", equalTo(null));
}

@Test
public void testXmlExampleInGuides() throws IOException {

Response createUser = UtilIT.createRandomUser();
String username = UtilIT.getUsernameFromResponse(createUser);
String apiToken = UtilIT.getApiTokenFromResponse(createUser);

Response createDataverse = UtilIT.createRandomDataverse(apiToken);
createDataverse.prettyPrint();
createDataverse.then().assertThat()
.statusCode(CREATED.getStatusCode());
String dataverseAlias = UtilIT.getAliasFromResponse(createDataverse);

File exampleFile = new File("doc/sphinx-guides/source/api/sword-atom-entry.xml");
String xmlIn = new String(java.nio.file.Files.readAllBytes(Paths.get(exampleFile.getAbsolutePath())));
Response createDataset = UtilIT.createDatasetViaSwordApiFromXML(dataverseAlias, xmlIn, apiToken);
createDataset.prettyPrint();
createDataset.then().assertThat()
.statusCode(CREATED.getStatusCode());

}

/**
* This test requires the root dataverse to have been published already.
*
Expand Down
29 changes: 28 additions & 1 deletion src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,18 @@ static Response createDatasetViaSwordApi(String dataverseToCreateDatasetIn, Stri
return createDatasetViaSwordApiFromXML(dataverseToCreateDatasetIn, xmlIn, apiToken);
}

private static Response createDatasetViaSwordApiFromXML(String dataverseToCreateDatasetIn, String xmlIn, String apiToken) {
static Response createDatasetViaSwordApi(String dataverseToCreateDatasetIn, String title, String description, String license, String apiToken) {
String nullRights = null;
String xmlIn = getDatasetXml(title, "Lastname, Firstname", description, license, nullRights);
return createDatasetViaSwordApiFromXML(dataverseToCreateDatasetIn, xmlIn, apiToken);
}

static Response createDatasetViaSwordApi(String dataverseToCreateDatasetIn, String title, String description, String license, String rights, String apiToken) {
String xmlIn = getDatasetXml(title, "Lastname, Firstname", description, license, rights);
return createDatasetViaSwordApiFromXML(dataverseToCreateDatasetIn, xmlIn, apiToken);
}

public static Response createDatasetViaSwordApiFromXML(String dataverseToCreateDatasetIn, String xmlIn, String apiToken) {
Response createDatasetResponse = given()
.auth().basic(apiToken, EMPTY_STRING)
.body(xmlIn)
Expand Down Expand Up @@ -534,11 +545,27 @@ static Response loadMetadataBlock(String apiToken, byte[] body) {
}

static private String getDatasetXml(String title, String author, String description) {
String nullLicense = null;
String nullRights = null;
return getDatasetXml(title, author, description, nullLicense, nullRights);
}

static private String getDatasetXml(String title, String author, String description, String license, String rights) {
String optionalLicense = "";
if (license != null) {
optionalLicense = " <dcterms:license>" + license + "</dcterms:license>\n";
}
String optionalRights = "";
if (rights != null) {
optionalRights = " <dcterms:rights>" + rights + "</dcterms:rights>\n";
}
String xmlIn = "<?xml version=\"1.0\"?>\n"
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:dcterms=\"http://purl.org/dc/terms/\">\n"
+ " <dcterms:title>" + title + "</dcterms:title>\n"
+ " <dcterms:creator>" + author + "</dcterms:creator>\n"
+ " <dcterms:description>" + description + "</dcterms:description>\n"
+ optionalLicense
+ optionalRights
+ "</entry>\n"
+ "";
return xmlIn;
Expand Down

0 comments on commit 1541391

Please sign in to comment.