Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IQSS/10883-License Enhancements #11232

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions doc/release-notes/10883-license improvements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
- License metadata enhancements (#10883):
- Added new fields to licenses: rightsIdentifier, rightsIdentifierScheme, schemeUri, languageCode
- Updated DataCite metadata export to include rightsIdentifier, rightsIdentifierScheme, and schemeUri consistent with the DataCite 4.5 schema and examples
- Enhanced metadata exports to include all new license fields
- Existing licenses from the example set included with Dataverse will be automatically updated with new fields
- Existing API calls support the new optional fields

Setup: For existing published datasets, the additional license metadata will not be available from DataCite or in metadata exports until the dataset is republished or
- the /api/admin/metadata/{id}/reExportDataset is run for the dataset
- the api/datasets/{id}/modifyRegistrationMetadata API is run for the dataset,
or the global version of these api calls (/api/admin/metadata/reExportAll, /api/datasets/modifyRegistrationPIDMetadataAll) are used.

8 changes: 6 additions & 2 deletions doc/sphinx-guides/source/_static/api/add-license.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"shortDescription": "Creative Commons Attribution 4.0 International License.",
"iconUrl": "https://i.creativecommons.org/l/by/4.0/88x31.png",
"active": true,
"sortOrder": 2
}
"sortOrder": 2,
"rightsIdentifier": "CC-BY-4.0",
"rightsIdentifierScheme": "SPDX",
"schemeUri": "https://spdx.org/licenses/",
"languageCode": "en"
}
18 changes: 16 additions & 2 deletions doc/sphinx-guides/source/api/native-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1484,7 +1484,12 @@ It returns a list of versions with their metadata, and file list:
"createTime": "2015-04-20T09:57:32Z",
"license": {
"name": "CC0 1.0",
"uri": "http://creativecommons.org/publicdomain/zero/1.0"
"uri": "http://creativecommons.org/publicdomain/zero/1.0",
"iconUri": "https://licensebuttons.net/p/zero/1.0/88x31.png",
"rightsIdentifier": "CC0",
"rightsIdentifierScheme": "Creative Commons",
"schemeUri": "https://creativecommons.org/",
"languageCode": "en",
},
"termsOfAccess": "You need to request for access.",
"fileAccessRequest": true,
Expand All @@ -1505,7 +1510,12 @@ It returns a list of versions with their metadata, and file list:
"createTime": "2015-04-20T09:43:45Z",
"license": {
"name": "CC0 1.0",
"uri": "http://creativecommons.org/publicdomain/zero/1.0"
"uri": "http://creativecommons.org/publicdomain/zero/1.0",
"iconUri": "https://licensebuttons.net/p/zero/1.0/88x31.png",
"rightsIdentifier": "CC0",
"rightsIdentifierScheme": "Creative Commons",
"schemeUri": "https://creativecommons.org/",
"languageCode": "en",
},
"termsOfAccess": "You need to request for access.",
"fileAccessRequest": true,
Expand Down Expand Up @@ -6836,6 +6846,10 @@ View the details of the standard license with the database ID specified in ``$ID

Superusers can add a new license by posting a JSON file adapted from this example :download:`add-license.json <../_static/api/add-license.json>`. The ``name`` and ``uri`` of the new license must be unique. Sort order field is mandatory. If you are interested in adding a Creative Commons license, you are encouarged to use the JSON files under :ref:`adding-creative-commons-licenses`:

Licenses must have a "name" and "uri" and may have the following optional fields: "shortDescription", "iconUri", "rightsIdentifier", "rightsIdentifierScheme", "schemeUri", "languageCode", "active", "sortOrder".
The "name" and "uri" are used to display the license in the user interface, with "shortDescription" and "iconUri" being used to enhance the display if available.
The "rightsIdentifier", "rightsIdentifierScheme", and "schemeUri" should be added if the license is available from https://spdx.org . "languageCode" should be sent if the language is not in English ("en"). "active" is a boolean indicating whether the license should be shown to users as an option. "sortOrder" is a numeric value - licenses are shown in the relative numeric order of this value.

.. code-block:: bash

export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Expand Down
17 changes: 10 additions & 7 deletions scripts/api/data/licenses/licenseApache-2.0.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
{
"name": "Apache-2.0",
"uri": "http://www.apache.org/licenses/LICENSE-2.0",
"shortDescription": "Apache License 2.0",
"active": true,
"sortOrder": 9
}

"name": "Apache-2.0",
"uri": "http://www.apache.org/licenses/LICENSE-2.0",
"shortDescription": "Apache License 2.0",
"active": true,
"sortOrder": 9,
"rightsIdentifier": "Apache-2.0",
"rightsIdentifierScheme": "SPDX",
"schemeUri": "https://spdx.org/licenses/",
"languageCode": "en"
}
8 changes: 6 additions & 2 deletions scripts/api/data/licenses/licenseCC-BY-4.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"shortDescription": "Creative Commons Attribution 4.0 International License.",
"iconUrl": "https://licensebuttons.net/l/by/4.0/88x31.png",
"active": true,
"sortOrder": 2
}
"sortOrder": 2,
"rightsIdentifier": "CC-BY-4.0",
"rightsIdentifierScheme": "SPDX",
"schemeUri": "https://spdx.org/licenses/",
"languageCode": "en"
}
6 changes: 5 additions & 1 deletion scripts/api/data/licenses/licenseCC-BY-NC-4.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"shortDescription": "Creative Commons Attribution-NonCommercial 4.0 International License.",
"iconUrl": "https://licensebuttons.net/l/by-nc/4.0/88x31.png",
"active": true,
"sortOrder": 4
"sortOrder": 4,
"rightsIdentifier": "CC-BY-NC-4.0",
"rightsIdentifierScheme": "SPDX",
"schemeUri": "https://spdx.org/licenses/",
"languageCode": "en"
}
6 changes: 5 additions & 1 deletion scripts/api/data/licenses/licenseCC-BY-NC-ND-4.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"shortDescription": "Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.",
"iconUrl": "https://licensebuttons.net/l/by-nc-nd/4.0/88x31.png",
"active": true,
"sortOrder": 7
"sortOrder": 7,
"rightsIdentifier": "CC-BY-NC-ND-4.0",
"rightsIdentifierScheme": "SPDX",
"schemeUri": "https://spdx.org/licenses/",
"languageCode": "en"
}
6 changes: 5 additions & 1 deletion scripts/api/data/licenses/licenseCC-BY-NC-SA-4.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"shortDescription": "Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.",
"iconUrl": "https://licensebuttons.net/l/by-nc-sa/4.0/88x31.png",
"active": true,
"sortOrder": 3
"sortOrder": 3,
"rightsIdentifier": "CC-BY-NC-SA-4.0",
"rightsIdentifierScheme": "SPDX",
"schemeUri": "https://spdx.org/licenses/",
"languageCode": "en"
}
6 changes: 5 additions & 1 deletion scripts/api/data/licenses/licenseCC-BY-ND-4.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"shortDescription": "Creative Commons Attribution-NoDerivatives 4.0 International License.",
"iconUrl": "https://licensebuttons.net/l/by-nd/4.0/88x31.png",
"active": true,
"sortOrder": 6
"sortOrder": 6,
"rightsIdentifier": "CC-BY-ND-4.0",
"rightsIdentifierScheme": "SPDX",
"schemeUri": "https://spdx.org/licenses/",
"languageCode": "en"
}
6 changes: 5 additions & 1 deletion scripts/api/data/licenses/licenseCC-BY-SA-4.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"shortDescription": "Creative Commons Attribution-ShareAlike 4.0 International License.",
"iconUrl": "https://licensebuttons.net/l/by-sa/4.0/88x31.png",
"active": true,
"sortOrder": 5
"sortOrder": 5,
"rightsIdentifier": "CC-BY-SA-4.0",
"rightsIdentifierScheme": "SPDX",
"schemeUri": "https://spdx.org/licenses/",
"languageCode": "en"
}
6 changes: 5 additions & 1 deletion scripts/api/data/licenses/licenseCC0-1.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"shortDescription": "Creative Commons CC0 1.0 Universal Public Domain Dedication.",
"iconUrl": "https://licensebuttons.net/p/zero/1.0/88x31.png",
"active": true,
"sortOrder": 1
"sortOrder": 1,
"rightsIdentifier": "CC0-1.0",
"rightsIdentifierScheme": "SPDX",
"schemeUri": "https://spdx.org/licenses/",
"languageCode": "en"
}
6 changes: 5 additions & 1 deletion scripts/api/data/licenses/licenseMIT.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,9 @@
"uri": "https://opensource.org/licenses/MIT",
"shortDescription": "MIT License",
"active": true,
"sortOrder": 8
"sortOrder": 8,
"rightsIdentifier": "MIT",
"rightsIdentifierScheme": "SPDX",
"schemeUri": "https://spdx.org/licenses/",
"languageCode": "en"
}
72 changes: 62 additions & 10 deletions src/main/java/edu/harvard/iq/dataverse/license/License.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,22 +52,22 @@
@UniqueConstraint(columnNames = "uri")}
)
public class License {
public static String CC0 = "http://creativecommons.org/publicdomain/zero/1.0";
public static String CC0 = "http://creativecommons.org/publicdomain/zero/1.0";

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(columnDefinition="TEXT", nullable = false, unique = true)
@Column(columnDefinition = "TEXT", nullable = false, unique = true)
private String name;

@Column(columnDefinition="TEXT")
@Column(columnDefinition = "TEXT")
private String shortDescription;

@Column(columnDefinition="TEXT", nullable = false, unique = true)
@Column(columnDefinition = "TEXT", nullable = false, unique = true)
private String uri;

@Column(columnDefinition="TEXT")
@Column(columnDefinition = "TEXT")
private String iconUrl;

@Column(nullable = false)
Expand All @@ -78,8 +78,20 @@ public class License {

@Column(nullable = false, columnDefinition = "BIGINT NOT NULL DEFAULT 0")
private Long sortOrder;

@Column(name = "rights_identifier")
private String rightsIdentifier;

@Column(name = "rights_identifier_scheme")
private String rightsIdentifierScheme;

@Column(name = "scheme_uri")
private String schemeUri;

@OneToMany(mappedBy="license")
@Column(name = "language_code")
private String languageCode;

@OneToMany(mappedBy = "license")
private List<TermsOfUseAndAccess> termsOfUseAndAccess;

public License() {
Expand Down Expand Up @@ -186,18 +198,55 @@ public void setSortOrder(Long sortOrder) {
this.sortOrder = sortOrder;
}

public String getRightsIdentifier() {
return rightsIdentifier;
}

public void setRightsIdentifier(String rightsIdentifier) {
this.rightsIdentifier = rightsIdentifier;
}

public String getRightsIdentifierScheme() {
return rightsIdentifierScheme;
}

public void setRightsIdentifierScheme(String rightsIdentifierScheme) {
this.rightsIdentifierScheme = rightsIdentifierScheme;
}

public String getSchemeUri() {
return schemeUri;
}

public void setSchemeUri(String schemeUri) {
this.schemeUri = schemeUri;
}

public String getLanguageCode() {
return languageCode;
}

public void setLanguageCode(String languageCode) {
this.languageCode = languageCode;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
License license = (License) o;
return active == license.active && id.equals(license.id) && name.equals(license.name) && shortDescription.equals(license.shortDescription) && uri.equals(license.uri) && Objects.equals(iconUrl, license.iconUrl)
&& Objects.equals(sortOrder, license.sortOrder);
return active == license.active && id.equals(license.id) && name.equals(license.name)
&& shortDescription.equals(license.shortDescription) && uri.equals(license.uri)
&& Objects.equals(iconUrl, license.iconUrl) && Objects.equals(sortOrder, license.sortOrder)
&& Objects.equals(rightsIdentifier, license.rightsIdentifier)
&& Objects.equals(rightsIdentifierScheme, license.rightsIdentifierScheme)
&& Objects.equals(schemeUri, license.schemeUri);
}

@Override
public int hashCode() {
return Objects.hash(id, name, shortDescription, uri, iconUrl, active, sortOrder);
return Objects.hash(id, name, shortDescription, uri, iconUrl, active, sortOrder, rightsIdentifier,
rightsIdentifierScheme, schemeUri);
}

@Override
Expand All @@ -211,7 +260,10 @@ public String toString() {
", active=" + active +
", isDefault=" + isDefault +
", sortOrder=" + sortOrder +
", rightsIdentifier='" + rightsIdentifier + '\'' +
", rightsIdentifierScheme='" + rightsIdentifierScheme + '\'' +
", schemeUri='" + schemeUri + '\'' +
'}';
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -1251,10 +1251,30 @@ private void writeAccessRights(XMLStreamWriter xmlw, DvObject dvObject) throws X
}
xmlw.writeEndElement(); // </rights>
xmlw.writeStartElement("rights"); // <rights>

if (license != null) {
xmlw.writeAttribute("rightsURI", license.getUri().toString());
xmlw.writeCharacters(license.getName());
String label = license.getShortDescription();
if(StringUtils.isBlank(label)) {
//Use name as a backup in case the license has no short description
label = license.getName();
}
xmlw.writeCharacters(license.getShortDescription());

if (license.getRightsIdentifier() != null) {
xmlw.writeAttribute("rightsIdentifier", license.getRightsIdentifier());
}
if (license.getRightsIdentifierScheme() != null) {
xmlw.writeAttribute("rightsIdentifierScheme", license.getRightsIdentifierScheme());
}
if (license.getSchemeUri() != null) {
xmlw.writeAttribute("schemeURI", license.getSchemeUri());
}
String langCode = license.getLanguageCode();
if (StringUtils.isBlank(langCode)) {
langCode = "en";
}
xmlw.writeAttribute("xml:lang", langCode);
} else {
xmlw.writeAttribute("rightsURI", DatasetUtil.getLicenseURI(dv));
xmlw.writeCharacters(BundleUtil.getStringFromBundle("license.custom.description"));
Expand Down
18 changes: 15 additions & 3 deletions src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,7 @@ public static JsonObjectBuilder json(Retention retention) {
}

public static JsonObjectBuilder json(License license) {

return jsonObjectBuilder()
.add("id", license.getId())
.add("name", license.getName())
Expand All @@ -1274,7 +1275,11 @@ public static JsonObjectBuilder json(License license) {
.add("iconUrl", license.getIconUrl() == null ? null : license.getIconUrl().toString())
.add("active", license.isActive())
.add("isDefault", license.isDefault())
.add("sortOrder", license.getSortOrder());
.add("sortOrder", license.getSortOrder())
.add("rightsIdentifier", license.getRightsIdentifier())
.add("rightsIdentifierScheme", license.getRightsIdentifierScheme())
.add("schemeUri", license.getSchemeUri() == null ? null : license.getSchemeUri().toString())
.add("languageCode", license.getLanguageCode());
}

public static Collector<String, JsonArrayBuilder, JsonArrayBuilder> stringsToJsonArray() {
Expand Down Expand Up @@ -1428,8 +1433,15 @@ private static JsonObjectBuilder jsonLicense(DatasetVersion dsv) {
.add("name", DatasetUtil.getLicenseName(dsv))
.add("uri", DatasetUtil.getLicenseURI(dsv));
String licenseIconUri = DatasetUtil.getLicenseIcon(dsv);
if (licenseIconUri != null) {
licenseJsonObjectBuilder.add("iconUri", licenseIconUri);
licenseJsonObjectBuilder.add("iconUri", licenseIconUri);
License license = DatasetUtil.getLicense(dsv);
if(license != null) {
licenseJsonObjectBuilder.add("rightsIdentifier",license.getRightsIdentifier())
.add("rightsIdentifierScheme", license.getRightsIdentifierScheme())
.add("schemeUri", license.getSchemeUri())
.add("languageCode", license.getLanguageCode());
} else {
licenseJsonObjectBuilder.add("languageCode", BundleUtil.getDefaultLocale().getLanguage());
}
return licenseJsonObjectBuilder;
}
Expand Down
Loading