Skip to content

Commit c047d4b

Browse files
committed
Merge branch 'develop' into 11634-api-get-available-file-categories
2 parents d09f76c + e69cf6f commit c047d4b

File tree

22 files changed

+881
-42
lines changed

22 files changed

+881
-42
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The [API for listing the collections a dataset has been linked to](https://guides.dataverse.org/en/latest/admin/dataverses-datasets.html#list-collections-that-are-linked-from-a-dataset) (`api/datasets/$linked-dataset-id/links`) is no longer restricted to superusers. For unpublished datasets, users need the "View Unpublished Dataset" permission to access the API. Unpublished collections in the list require the "View Unpublished Dataverse" permission; otherwise, they are hidden.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
New endpoints have been implemented in the Dataverses API for the management of dataverse templates:
2+
3+
- POST `/dataverses/{id}/templates`: Creates a template for a given Dataverse collection ``id``.
4+
- GET `/dataverses/{id}/templates`: Lists the templates for a given Dataverse collection ``id``.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "Dataverse template",
3+
"isDefault": true,
4+
"fields": [
5+
{
6+
"typeName": "author",
7+
"value": [
8+
{
9+
"authorName": {
10+
"typeName": "authorName",
11+
"value": "Belicheck, Bill"
12+
},
13+
"authorAffiliation": {
14+
"typeName": "authorIdentifierScheme",
15+
"value": "ORCID"
16+
}
17+
}
18+
]
19+
}
20+
],
21+
"instructions": [
22+
{
23+
"instructionField": "author",
24+
"instructionText": "The author data"
25+
}
26+
]
27+
}

doc/sphinx-guides/source/api/native-api.rst

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,6 +1400,46 @@ The fully expanded example above (without environment variables) looks like this
14001400
14011401
curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -X GET "https://demo.dataverse.org/api/access/dataverseFeaturedItemImage/1"
14021402
1403+
List Templates of a Collection
1404+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1405+
1406+
Lists the templates for a given Dataverse collection ``id``:
1407+
1408+
.. code-block:: bash
1409+
1410+
export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
1411+
export SERVER_URL=https://demo.dataverse.org
1412+
export ID=1
1413+
1414+
curl -H "X-Dataverse-key:$API_TOKEN" -X GET "$SERVER_URL/api/dataverses/{ID}/templates"
1415+
1416+
The fully expanded example above (without environment variables) looks like this:
1417+
1418+
.. code-block:: bash
1419+
1420+
curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -X GET "https://demo.dataverse.org/api/dataverses/1/templates"
1421+
1422+
Create a Template for a Collection
1423+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1424+
1425+
Creates a template for a given Dataverse collection ``id``.
1426+
1427+
To create the template, you must send a JSON file. Your JSON file might look like :download:`dataverse-template.json <../_static/api/dataverse-template.json>` which you would send to the Dataverse installation like this:
1428+
1429+
.. code-block:: bash
1430+
1431+
export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
1432+
export SERVER_URL=https://demo.dataverse.org
1433+
export ID=1
1434+
1435+
curl -H "X-Dataverse-key: $API_TOKEN" -X POST "$SERVER_URL/api/dataverses/{ID}/templates" --upload-file dataverse-template.json
1436+
1437+
The fully expanded example above (without environment variables) looks like this:
1438+
1439+
.. code-block:: bash
1440+
1441+
curl -H "X-Dataverse-key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -X POST "https://demo.dataverse.org/api/dataverses/1/templates" --upload-file dataverse-template.json
1442+
14031443
Datasets
14041444
--------
14051445

doc/sphinx-guides/source/user/appendix.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ Supported Metadata
2323
Detailed below are what metadata schemas we support for Citation and Domain Specific Metadata in the Dataverse Project:
2424

2525
- Citation Metadata (`see .tsv <https://github.com/IQSS/dataverse/blob/master/scripts/api/data/metadatablocks/citation.tsv>`__): compliant with `DDI Lite <https://www.ddialliance.org/specification/ddi2.1/lite/index.html>`_, `DDI 2.5 Codebook <https://www.ddialliance.org/>`__, `DataCite 4.5 <https://schema.datacite.org/meta/kernel-4.5/>`__, and Dublin Core's `DCMI Metadata Terms <https://dublincore.org/documents/dcmi-terms/>`__ . Language field uses `ISO 639-1 <https://www.loc.gov/standards/iso639-2/php/English_list.php>`__ controlled vocabulary.
26-
- Geospatial Metadata (`see .tsv <https://github.com/IQSS/dataverse/blob/master/scripts/api/data/metadatablocks/geospatial.tsv>`__): compliant with `DDI Lite <https://www.ddialliance.org/specification/ddi2.1/lite/index.html>`_, `DDI 2.5 Codebook <https://www.ddialliance.org/>`__, `DataCite 4.5 <https://schema.datacite.org/meta/kernel-4.5/>`__, and Dublin Core. Country / Nation field uses `ISO 3166-1 <https://en.wikipedia.org/wiki/ISO_3166-1>`_ controlled vocabulary.
26+
- Geospatial Metadata (`see .tsv <https://github.com/IQSS/dataverse/blob/master/scripts/api/data/metadatablocks/geospatial.tsv>`__): compliant with `DDI Lite <https://www.ddialliance.org/specification/ddi2.1/lite/index.html>`_, `DDI 2.5 Codebook <https://www.ddialliance.org/>`__, `DataCite 4.5 <https://schema.datacite.org/meta/kernel-4.5/>`__, and Dublin Core. Country / Nation field uses `ISO 3166-1 <https://en.wikipedia.org/wiki/ISO_3166-1>`_ controlled vocabulary.
27+
28+
- Please note that a new and improved Geospatial metadata block is being proposed at `<https://github.com/IQSS/dataverse/pull/11507>`__. We encourage you to try the block and give feedback in that pull request.
2729
- Social Science & Humanities Metadata (`see .tsv <https://github.com/IQSS/dataverse/blob/master/scripts/api/data/metadatablocks/social_science.tsv>`__): compliant with `DDI Lite <https://www.ddialliance.org/specification/ddi2.1/lite/index.html>`_, `DDI 2.5 Codebook <https://www.ddialliance.org/>`__, and Dublin Core.
2830
- Astronomy and Astrophysics Metadata (`see .tsv <https://github.com/IQSS/dataverse/blob/master/scripts/api/data/metadatablocks/astrophysics.tsv>`__): These metadata elements can be mapped/exported to the International Virtual Observatory Alliance’s (IVOA)
2931
`VOResource Schema format <https://www.ivoa.net/documents/latest/RM.html>`__ and is based on

src/main/java/edu/harvard/iq/dataverse/EjbDataverseEngine.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import edu.harvard.iq.dataverse.authorization.AuthenticationServiceBean;
77
import edu.harvard.iq.dataverse.authorization.providers.builtin.BuiltinUserServiceBean;
88
import edu.harvard.iq.dataverse.dataverse.featured.DataverseFeaturedItemServiceBean;
9+
import edu.harvard.iq.dataverse.license.LicenseServiceBean;
910
import edu.harvard.iq.dataverse.util.cache.CacheFactoryBean;
1011
import edu.harvard.iq.dataverse.engine.DataverseEngine;
1112
import edu.harvard.iq.dataverse.authorization.Permission;
@@ -192,6 +193,9 @@ public class EjbDataverseEngine {
192193
@EJB
193194
DataverseFeaturedItemServiceBean dataverseFeaturedItemServiceBean;
194195

196+
@EJB
197+
LicenseServiceBean licenseServiceBean;
198+
195199
@EJB
196200
DatasetFieldsValidator datasetFieldsValidator;
197201

@@ -541,6 +545,11 @@ public DatasetFieldsValidator datasetFieldsValidator() {
541545
return datasetFieldsValidator;
542546
}
543547

548+
@Override
549+
public LicenseServiceBean licenses() {
550+
return licenseServiceBean;
551+
}
552+
544553
@Override
545554
public StorageUseServiceBean storageUse() {
546555
return storageUseService;

src/main/java/edu/harvard/iq/dataverse/Template.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,11 @@ public List<DatasetField> getDatasetFields() {
137137

138138
@Transient
139139
private Map<String, String> instructionsMap = null;
140-
140+
141+
public void setInstructionsMap(Map<String, String> instructionsMap) {
142+
this.instructionsMap = instructionsMap;
143+
}
144+
141145
@Transient
142146
private TreeMap<MetadataBlock, List<DatasetField>> metadataBlocksForView = new TreeMap<>();
143147
@Transient

src/main/java/edu/harvard/iq/dataverse/api/Datasets.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2089,20 +2089,23 @@ public Response getCustomTermsTab(@PathParam("id") String id, @PathParam("versio
20892089
public Response getLinks(@Context ContainerRequestContext crc, @PathParam("id") String idSupplied ) {
20902090
try {
20912091
User u = getRequestUser(crc);
2092-
if (!u.isSuperuser()) {
2093-
return error(Response.Status.FORBIDDEN, "Not a superuser");
2094-
}
20952092
Dataset dataset = findDatasetOrDie(idSupplied);
20962093

2094+
if (!dataset.isReleased() && !permissionService.hasPermissionsFor(u, dataset, EnumSet.of(Permission.ViewUnpublishedDataset))) {
2095+
return error(Response.Status.FORBIDDEN, "User is not allowed to list the link(s) of this dataset");
2096+
}
2097+
20972098
long datasetId = dataset.getId();
20982099
List<Dataverse> dvsThatLinkToThisDatasetId = dataverseSvc.findDataversesThatLinkToThisDatasetId(datasetId);
20992100
JsonArrayBuilder dataversesThatLinkToThisDatasetIdBuilder = Json.createArrayBuilder();
21002101
for (Dataverse dataverse : dvsThatLinkToThisDatasetId) {
2101-
JsonObjectBuilder datasetBuilder = Json.createObjectBuilder();
2102-
datasetBuilder.add("id", dataverse.getId());
2103-
datasetBuilder.add("alias", dataverse.getAlias());
2104-
datasetBuilder.add("displayName", dataverse.getDisplayName());
2105-
dataversesThatLinkToThisDatasetIdBuilder.add(datasetBuilder.build());
2102+
if (dataverse.isReleased() || this.permissionService.hasPermissionsFor(u, dataverse, EnumSet.of(Permission.ViewUnpublishedDataverse))) {
2103+
JsonObjectBuilder datasetBuilder = Json.createObjectBuilder();
2104+
datasetBuilder.add("id", dataverse.getId());
2105+
datasetBuilder.add("alias", dataverse.getAlias());
2106+
datasetBuilder.add("displayName", dataverse.getDisplayName());
2107+
dataversesThatLinkToThisDatasetIdBuilder.add(datasetBuilder.build());
2108+
}
21062109
}
21072110
JsonObjectBuilder response = Json.createObjectBuilder();
21082111
response.add("id", datasetId);

src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1931,4 +1931,34 @@ public Response deleteFeaturedItems(@Context ContainerRequestContext crc, @PathP
19311931
return e.getResponse();
19321932
}
19331933
}
1934+
1935+
@GET
1936+
@AuthRequired
1937+
@Path("{identifier}/templates")
1938+
public Response getTemplates(@Context ContainerRequestContext crc, @PathParam("identifier") String dvIdtf) {
1939+
try {
1940+
Dataverse dataverse = findDataverseOrDie(dvIdtf);
1941+
return ok(jsonTemplates(execCommand(new ListDataverseTemplatesCommand(createDataverseRequest(getRequestUser(crc)), dataverse))));
1942+
} catch (WrappedResponse e) {
1943+
return e.getResponse();
1944+
}
1945+
}
1946+
1947+
@POST
1948+
@AuthRequired
1949+
@Path("{identifier}/templates")
1950+
public Response createTemplate(@Context ContainerRequestContext crc, String body, @PathParam("identifier") String dvIdtf) {
1951+
try {
1952+
Dataverse dataverse = findDataverseOrDie(dvIdtf);
1953+
NewTemplateDTO newTemplateDTO;
1954+
try {
1955+
newTemplateDTO = NewTemplateDTO.fromRequestBody(body, jsonParser());
1956+
} catch (JsonParseException ex) {
1957+
return error(Status.BAD_REQUEST, MessageFormat.format(BundleUtil.getStringFromBundle("dataverse.createTemplate.error.jsonParseMetadataFields"), ex.getMessage()));
1958+
}
1959+
return ok(jsonTemplate(execCommand(new CreateTemplateCommand(newTemplateDTO.toTemplate(), createDataverseRequest(getRequestUser(crc)), dataverse, true))));
1960+
} catch (WrappedResponse e) {
1961+
return e.getResponse();
1962+
}
1963+
}
19341964
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package edu.harvard.iq.dataverse.api.dto;
2+
3+
import edu.harvard.iq.dataverse.*;
4+
import edu.harvard.iq.dataverse.util.json.JsonParseException;
5+
import edu.harvard.iq.dataverse.util.json.JsonParser;
6+
import edu.harvard.iq.dataverse.util.json.JsonUtil;
7+
import jakarta.json.*;
8+
9+
import java.sql.Timestamp;
10+
import java.util.*;
11+
12+
public class NewTemplateDTO {
13+
14+
private String name;
15+
private List<DatasetField> datasetFields;
16+
private Map<String, String> instructionsMap;
17+
private boolean isDefault;
18+
19+
public static NewTemplateDTO fromRequestBody(String requestBody, JsonParser jsonParser) throws JsonParseException {
20+
NewTemplateDTO newTemplateDTO = new NewTemplateDTO();
21+
22+
JsonObject jsonObject = JsonUtil.getJsonObject(requestBody);
23+
24+
newTemplateDTO.name = jsonObject.getString("name");
25+
newTemplateDTO.datasetFields = jsonParser.parseMultipleFields(jsonObject);
26+
newTemplateDTO.instructionsMap = parseRequestBodyInstructionsMap(jsonObject);
27+
newTemplateDTO.isDefault = jsonObject.getBoolean("isDefault", false);
28+
29+
return newTemplateDTO;
30+
}
31+
32+
public Template toTemplate() {
33+
Template template = new Template();
34+
35+
template.setDatasetFields(getDatasetFields());
36+
template.setName(getName());
37+
template.setInstructionsMap(getInstructionsMap());
38+
template.updateInstructions();
39+
template.setCreateTime(new Timestamp(new Date().getTime()));
40+
template.setUsageCount(0L);
41+
42+
return template;
43+
}
44+
45+
public String getName() {
46+
return name;
47+
}
48+
49+
public List<DatasetField> getDatasetFields() {
50+
return datasetFields;
51+
}
52+
53+
public Map<String, String> getInstructionsMap() {
54+
return instructionsMap;
55+
}
56+
57+
public boolean isDefault() {
58+
return isDefault;
59+
}
60+
61+
private static Map<String, String> parseRequestBodyInstructionsMap(JsonObject jsonObject) {
62+
Map<String, String> instructionsMap = new HashMap<>();
63+
JsonArray instructionsJsonArray = jsonObject.getJsonArray("instructions");
64+
if (instructionsJsonArray == null) {
65+
return null;
66+
}
67+
for (JsonObject instructionJsonObject : instructionsJsonArray.getValuesAs(JsonObject.class)) {
68+
instructionsMap.put(
69+
instructionJsonObject.getString("instructionField"),
70+
instructionJsonObject.getString("instructionText")
71+
);
72+
}
73+
return instructionsMap;
74+
}
75+
}

0 commit comments

Comments
 (0)