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

Extend Datasets API to support dataset deaccession and recovery of files and file counts of deaccessioned datasets #9937

Merged
merged 40 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
37136c0
Added: optional includeDeaccessioned parameter for getVersionFiles AP…
GPortas Sep 12, 2023
c6b38e4
Merge branch '9851-datafile-payload-extension' of github.com:IQSS/dat…
GPortas Sep 12, 2023
1299855
Stash: deaccessionDataset API endpoint WIP
GPortas Sep 16, 2023
bbfdff3
Added: deaccessionDataset API endpoint (pending IT)
GPortas Sep 20, 2023
b19fb82
Added: deaccessionDataset API endpoint IT
GPortas Sep 20, 2023
b6ce32b
Refactor: dataset version string identifiers extracted to constants
GPortas Sep 20, 2023
887d26f
Added: docs for deaccessioning API endpoints
GPortas Sep 21, 2023
b007166
Merge branch '9851-datafile-payload-extension' of github.com:IQSS/dat…
GPortas Sep 21, 2023
1d661e7
Added: release notes for #9852
GPortas Sep 21, 2023
3c7fa8f
Added: friendlyType field to DataFile API json payload
GPortas Sep 21, 2023
3dd4564
Added: ignoreOriginalTabularSize optional query parameter to getDownl…
GPortas Sep 26, 2023
f653c21
Changed: dataset version download size calculation when ignoring orig…
GPortas Sep 27, 2023
9d10b99
Added: #9958 release notes
GPortas Sep 27, 2023
9710c79
Added: mentioned ignoreOriginalTabularSize query parameter in the doc…
GPortas Sep 27, 2023
4aa34ff
Added: ignoreOriginalTabularSize query param usage example to the docs
GPortas Sep 27, 2023
448ae44
Added: JSON payload to curl examples for Deaccession Dataset docs
GPortas Sep 28, 2023
907fd40
Changed: using query-based implementation for files download size
GPortas Oct 2, 2023
a5c32bd
Added: error case to getDownloadSize IT
GPortas Oct 2, 2023
131cd8f
Added: multiple tab files test case for getDownloadSize IT
GPortas Oct 2, 2023
725bbb7
Changed: updated docs for /downloadsize endpoint
GPortas Oct 2, 2023
cbf00d7
Changed: updated release notes for #9958
GPortas Oct 2, 2023
87c6515
Added: sleep call to getDownloadSize IT to ensure tab file is ingested
GPortas Oct 2, 2023
38cabc1
Changed: getVersionFiles docs suggestions applied
GPortas Oct 2, 2023
5c7830c
Changed: getVersionFiles docs suggestions applied (2)
GPortas Oct 2, 2023
02003f1
Added: clarification to Deaccession Dataset API docs about calling th…
GPortas Oct 2, 2023
567fcb8
Merge branch '9852-files-api-deaccessioned-datasets' of github.com:IQ…
GPortas Oct 2, 2023
244ade8
tiny doc fixes #9852
pdurbin Oct 2, 2023
649ea13
Changed: using POST method for deaccessionDataset API endpoint and st…
GPortas Oct 2, 2023
122bbd6
Merge branch '9852-files-api-deaccessioned-datasets' of github.com:IQ…
GPortas Oct 2, 2023
4561e83
Refactor: simpler where condition for getOriginalTabularFilesSize query
GPortas Oct 3, 2023
47da5a4
Changed: using the known size of the tab file in IT instead of obtain…
GPortas Oct 3, 2023
b76576d
Merge branch '9852-files-api-deaccessioned-datasets' of github.com:IQ…
GPortas Oct 3, 2023
91db302
Fixed: failing IT due to missing params when calling deaccessionDataset
GPortas Oct 3, 2023
abcc962
Merge branch '9852-files-api-deaccessioned-datasets' of github.com:IQ…
GPortas Oct 3, 2023
3d3a553
Merge pull request #9960 from IQSS/9958-dataset-files-size
kcondon Oct 12, 2023
c8f2086
Merge branch 'develop' of github.com:IQSS/dataverse into 9852-files-a…
GPortas Oct 12, 2023
ada8cc7
Fixed: curl examples in docs for deaccession dataset
GPortas Oct 13, 2023
1f0efdd
Fixed: permission checks in GetSpecificPublishedDatasetVersionCommand
GPortas Oct 13, 2023
61712db
Merge branch 'develop' of github.com:IQSS/dataverse into 9852-files-a…
GPortas Oct 13, 2023
12ba35e
Fixed: failing tests after develop merge
GPortas Oct 13, 2023
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/9852-files-api-extension-deaccession.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Extended the existing endpoints:

- getVersionFiles (/api/datasets/{id}/versions/{versionId}/files)
- getVersionFileCounts (/api/datasets/{id}/versions/{versionId}/files/counts)

The above endpoints now accept a new boolean optional query parameter "includeDeaccessioned", which, if enabled, causes the endpoint to consider deaccessioned versions when searching for versions to obtain files or file counts.

Additionally, a new endpoint has been developed to support version deaccessioning through API (Given a dataset and a version).

- deaccessionDataset (/api/datasets/{id}/versions/{versionId}/deaccession)

Finally, the DataFile API payload has been extended to add the field "friendlyType"
45 changes: 44 additions & 1 deletion doc/sphinx-guides/source/api/native-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1020,7 +1020,17 @@ Usage example:

Please note that both filtering and ordering criteria values are case sensitive and must be correctly typed for the endpoint to recognize them.

Keep in mind that you can combine all of the above query params depending on the results you are looking for.
By default, deaccessioned dataset versions are not included in the search when applying the :latest or :latest-published identifiers. Additionally, when filtering by a specific version tag, you will get a "not found" error if the version is deaccessioned and you do not enable the ``includeDeaccessioned`` option described below.

If you want to consider deaccessioned dataset versions, you must set ``includeDeaccessioned`` query parameter to ``true``.

Usage example:

.. code-block:: bash

curl "https://demo.dataverse.org/api/datasets/24/versions/1.0/files?includeDeaccessioned=true"

.. note:: Keep in mind that you can combine all of the above query params depending on the results you are looking for.

Get File Counts in a Dataset
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -1048,6 +1058,16 @@ The fully expanded example above (without environment variables) looks like this

curl "https://demo.dataverse.org/api/datasets/24/versions/1.0/files/counts"

By default, deaccessioned dataset versions are not supported by this endpoint and will be ignored in the search when applying the :latest or :latest-published identifiers. Additionally, when filtering by a specific version tag, you will get a not found error if the version is deaccessioned and you do not enable the option described below.
GPortas marked this conversation as resolved.
Show resolved Hide resolved

If you want to consider deaccessioned dataset versions, you must specify this through the ``includeDeaccessioned`` query parameter.

Usage example:

.. code-block:: bash

curl "https://demo.dataverse.org/api/datasets/24/versions/1.0/files/counts?includeDeaccessioned=true"

View Dataset Files and Folders as a Directory Index
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -1344,6 +1364,29 @@ The fully expanded example above (without environment variables) looks like this

curl -H "X-Dataverse-key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -X DELETE "https://demo.dataverse.org/api/datasets/24/versions/:draft"

Deaccession Dataset
~~~~~~~~~~~~~~~~~~~

Given a version of a dataset, updates its status to deaccessioned.
GPortas marked this conversation as resolved.
Show resolved Hide resolved

.. code-block:: bash

export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
export SERVER_URL=https://demo.dataverse.org
export ID=24
export VERSIONID=1.0
export JSON='{"deaccessionReason":"Description of the deaccession reason.", "deaccessionForwardURL":"https://demo.dataverse.org"}'
GPortas marked this conversation as resolved.
Show resolved Hide resolved

curl -H "X-Dataverse-key:$API_TOKEN" -X PUT "$SERVER_URL/api/datasets/$ID/versions/$VERSIONID/deaccession" -d "$JSON"

The fully expanded example above (without environment variables) looks like this:

.. code-block:: bash

curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -X PUT "https://demo.dataverse.org/api/datasets/24/versions/1.0/deaccession" -d '{"deaccessionReason":"Description of the deaccession reason.", "deaccessionForwardURL":"https://demo.dataverse.org"}'

.. note:: You cannot deaccession a dataset more than once. If you call this endpoint twice for the same dataset version, you will get a not found error on the second call, since the dataset you are looking for will no longer be public since it is already deaccessioned.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.. note:: You cannot deaccession a dataset more than once. If you call this endpoint twice for the same dataset version, you will get a not found error on the second call, since the dataset you are looking for will no longer be public since it is already deaccessioned.
.. note:: You cannot deaccession a dataset more than once. If you call this endpoint twice for the same dataset version, you will get a not found error on the second call, since the dataset you are looking for will no longer be published since it is already deaccessioned.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed this fix in 244ade8 with a couple other tiny doc fixes.


GPortas marked this conversation as resolved.
Show resolved Hide resolved
Set Citation Date Field Type for a Dataset
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
5 changes: 5 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/api/ApiConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,9 @@ private ApiConstants() {

// Authentication
public static final String CONTAINER_REQUEST_CONTEXT_USER = "user";

// Dataset
public static final String DS_VERSION_LATEST = ":latest";
public static final String DS_VERSION_DRAFT = ":draft";
public static final String DS_VERSION_LATEST_PUBLISHED = ":latest-published";
pdurbin marked this conversation as resolved.
Show resolved Hide resolved
}
74 changes: 54 additions & 20 deletions src/main/java/edu/harvard/iq/dataverse/api/Datasets.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import edu.harvard.iq.dataverse.engine.command.impl.CreateDatasetVersionCommand;
import edu.harvard.iq.dataverse.engine.command.impl.CreatePrivateUrlCommand;
import edu.harvard.iq.dataverse.engine.command.impl.CuratePublishedDatasetVersionCommand;
import edu.harvard.iq.dataverse.engine.command.impl.DeaccessionDatasetVersionCommand;
import edu.harvard.iq.dataverse.engine.command.impl.DeleteDatasetCommand;
import edu.harvard.iq.dataverse.engine.command.impl.DeleteDatasetVersionCommand;
import edu.harvard.iq.dataverse.engine.command.impl.DeleteDatasetLinkingDataverseCommand;
Expand Down Expand Up @@ -97,6 +98,7 @@
import edu.harvard.iq.dataverse.util.json.JsonUtil;
import edu.harvard.iq.dataverse.search.IndexServiceBean;

import static edu.harvard.iq.dataverse.api.ApiConstants.*;
import static edu.harvard.iq.dataverse.util.json.JsonPrinter.*;
import static edu.harvard.iq.dataverse.util.json.NullSafeJsonBuilder.jsonObjectBuilder;
import edu.harvard.iq.dataverse.util.json.NullSafeJsonBuilder;
Expand Down Expand Up @@ -390,8 +392,8 @@ public Response destroyDataset(@Context ContainerRequestContext crc, @PathParam(
@AuthRequired
@Path("{id}/versions/{versionId}")
public Response deleteDraftVersion(@Context ContainerRequestContext crc, @PathParam("id") String id, @PathParam("versionId") String versionId ){
if ( ! ":draft".equals(versionId) ) {
return badRequest("Only the :draft version can be deleted");
if (!DS_VERSION_DRAFT.equals(versionId)) {
return badRequest("Only the " + DS_VERSION_DRAFT + " version can be deleted");
}

return response( req -> {
Expand Down Expand Up @@ -501,10 +503,11 @@ public Response getVersionFiles(@Context ContainerRequestContext crc,
@QueryParam("categoryName") String categoryName,
@QueryParam("searchText") String searchText,
@QueryParam("orderCriteria") String orderCriteria,
@QueryParam("includeDeaccessioned") boolean includeDeaccessioned,
@Context UriInfo uriInfo,
@Context HttpHeaders headers) {
return response(req -> {
DatasetVersion datasetVersion = getDatasetVersionOrDie(req, versionId, findDatasetOrDie(datasetId), uriInfo, headers);
DatasetVersion datasetVersion = getDatasetVersionOrDie(req, versionId, findDatasetOrDie(datasetId), uriInfo, headers, includeDeaccessioned);
DatasetVersionFilesServiceBean.FileMetadatasOrderCriteria fileMetadatasOrderCriteria;
try {
fileMetadatasOrderCriteria = orderCriteria != null ? DatasetVersionFilesServiceBean.FileMetadatasOrderCriteria.valueOf(orderCriteria) : DatasetVersionFilesServiceBean.FileMetadatasOrderCriteria.NameAZ;
Expand All @@ -524,9 +527,9 @@ public Response getVersionFiles(@Context ContainerRequestContext crc,
@GET
@AuthRequired
@Path("{id}/versions/{versionId}/files/counts")
public Response getVersionFileCounts(@Context ContainerRequestContext crc, @PathParam("id") String datasetId, @PathParam("versionId") String versionId, @Context UriInfo uriInfo, @Context HttpHeaders headers) {
public Response getVersionFileCounts(@Context ContainerRequestContext crc, @PathParam("id") String datasetId, @PathParam("versionId") String versionId, @QueryParam("includeDeaccessioned") boolean includeDeaccessioned, @Context UriInfo uriInfo, @Context HttpHeaders headers) {
return response(req -> {
DatasetVersion datasetVersion = getDatasetVersionOrDie(req, versionId, findDatasetOrDie(datasetId), uriInfo, headers);
DatasetVersion datasetVersion = getDatasetVersionOrDie(req, versionId, findDatasetOrDie(datasetId), uriInfo, headers, includeDeaccessioned);
JsonObjectBuilder jsonObjectBuilder = Json.createObjectBuilder();
jsonObjectBuilder.add("total", datasetVersionFilesServiceBean.getFileMetadataCount(datasetVersion));
jsonObjectBuilder.add("perContentType", json(datasetVersionFilesServiceBean.getFileMetadataCountPerContentType(datasetVersion)));
Expand All @@ -543,7 +546,7 @@ public Response getVersionFileCounts(@Context ContainerRequestContext crc, @Path
public Response getFileAccessFolderView(@Context ContainerRequestContext crc, @PathParam("id") String datasetId, @QueryParam("version") String versionId, @QueryParam("folder") String folderName, @QueryParam("original") Boolean originals, @Context UriInfo uriInfo, @Context HttpHeaders headers, @Context HttpServletResponse response) {

folderName = folderName == null ? "" : folderName;
versionId = versionId == null ? ":latest-published" : versionId;
versionId = versionId == null ? DS_VERSION_LATEST_PUBLISHED : versionId;

DatasetVersion version;
try {
Expand Down Expand Up @@ -618,8 +621,8 @@ public Response getVersionMetadataBlock(@Context ContainerRequestContext crc,
@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) ) {
return badRequest("Signposting is not supported on the :draft version");
if (DS_VERSION_DRAFT.equals(versionId)) {
return badRequest("Signposting is not supported on the " + DS_VERSION_DRAFT + " version");
}
User user = getRequestUser(crc);
return response(req -> {
Expand Down Expand Up @@ -704,10 +707,9 @@ public Response updateDatasetPIDMetadataAll(@Context ContainerRequestContext crc
@AuthRequired
@Path("{id}/versions/{versionId}")
@Consumes(MediaType.APPLICATION_JSON)
public Response updateDraftVersion(@Context ContainerRequestContext crc, String jsonBody, @PathParam("id") String id, @PathParam("versionId") String versionId){

if ( ! ":draft".equals(versionId) ) {
return error( Response.Status.BAD_REQUEST, "Only the :draft version can be updated");
public Response updateDraftVersion(@Context ContainerRequestContext crc, String jsonBody, @PathParam("id") String id, @PathParam("versionId") String versionId) {
if (!DS_VERSION_DRAFT.equals(versionId)) {
return error( Response.Status.BAD_REQUEST, "Only the " + DS_VERSION_DRAFT + " version can be updated");
}

try ( StringReader rdr = new StringReader(jsonBody) ) {
Expand Down Expand Up @@ -790,7 +792,7 @@ public Response getVersionJsonLDMetadata(@Context ContainerRequestContext crc, @
@Path("{id}/metadata")
@Produces("application/ld+json, application/json-ld")
public Response getVersionJsonLDMetadata(@Context ContainerRequestContext crc, @PathParam("id") String id, @Context UriInfo uriInfo, @Context HttpHeaders headers) {
return getVersionJsonLDMetadata(crc, id, ":draft", uriInfo, headers);
return getVersionJsonLDMetadata(crc, id, DS_VERSION_DRAFT, uriInfo, headers);
}

@PUT
Expand Down Expand Up @@ -1724,7 +1726,7 @@ public Response getCustomTermsTab(@PathParam("id") String id, @PathParam("versio
return error(Status.NOT_FOUND, "This Dataset has no custom license");
}
persistentId = getRequestParameter(":persistentId".substring(1));
if (versionId.equals(":draft")) {
if (versionId.equals(DS_VERSION_DRAFT)) {
versionId = "DRAFT";
}
} catch (WrappedResponse wrappedResponse) {
Expand Down Expand Up @@ -2685,11 +2687,11 @@ private void msgt(String m) {
public static <T> T handleVersion(String versionId, DsVersionHandler<T> hdl)
throws WrappedResponse {
switch (versionId) {
case ":latest":
case DS_VERSION_LATEST:
return hdl.handleLatest();
case ":draft":
case DS_VERSION_DRAFT:
return hdl.handleDraft();
case ":latest-published":
case DS_VERSION_LATEST_PUBLISHED:
return hdl.handleLatestPublished();
default:
try {
Expand All @@ -2709,11 +2711,15 @@ public static <T> T handleVersion(String versionId, DsVersionHandler<T> hdl)
}

private DatasetVersion getDatasetVersionOrDie(final DataverseRequest req, String versionNumber, final Dataset ds, UriInfo uriInfo, HttpHeaders headers) throws WrappedResponse {
return getDatasetVersionOrDie(req, versionNumber, ds, uriInfo, headers, false);
}

private DatasetVersion getDatasetVersionOrDie(final DataverseRequest req, String versionNumber, final Dataset ds, UriInfo uriInfo, HttpHeaders headers, boolean includeDeaccessioned) throws WrappedResponse {
DatasetVersion dsv = execCommand(handleVersion(versionNumber, new DsVersionHandler<Command<DatasetVersion>>() {

@Override
public Command<DatasetVersion> handleLatest() {
return new GetLatestAccessibleDatasetVersionCommand(req, ds);
return new GetLatestAccessibleDatasetVersionCommand(req, ds, includeDeaccessioned);
}

@Override
Expand All @@ -2723,12 +2729,12 @@ public Command<DatasetVersion> handleDraft() {

@Override
public Command<DatasetVersion> handleSpecific(long major, long minor) {
return new GetSpecificPublishedDatasetVersionCommand(req, ds, major, minor);
return new GetSpecificPublishedDatasetVersionCommand(req, ds, major, minor, includeDeaccessioned);
}

@Override
public Command<DatasetVersion> handleLatestPublished() {
return new GetLatestPublishedDatasetVersionCommand(req, ds);
return new GetLatestPublishedDatasetVersionCommand(req, ds, includeDeaccessioned);
}
}));
if (dsv == null || dsv.getId() == null) {
Expand Down Expand Up @@ -3917,4 +3923,32 @@ public Response getDatasetVersionCitation(@Context ContainerRequestContext crc,
return response(req -> ok(
getDatasetVersionOrDie(req, versionId, findDatasetOrDie(datasetId), uriInfo, headers).getCitation(true, false)), getRequestUser(crc));
}

@PUT
@AuthRequired
@Path("{id}/versions/{versionId}/deaccession")
public Response deaccessionDataset(@Context ContainerRequestContext crc, @PathParam("id") String datasetId, @PathParam("versionId") String versionId, String jsonBody, @Context UriInfo uriInfo, @Context HttpHeaders headers) {
if (DS_VERSION_DRAFT.equals(versionId) || DS_VERSION_LATEST.equals(versionId)) {
pdurbin marked this conversation as resolved.
Show resolved Hide resolved
return badRequest("Only " + DS_VERSION_LATEST_PUBLISHED + " or a specific version can be deaccessioned");
}
return response(req -> {
DatasetVersion datasetVersion = getDatasetVersionOrDie(req, versionId, findDatasetOrDie(datasetId), uriInfo, headers, false);
try (StringReader stringReader = new StringReader(jsonBody)) {
JsonObject jsonObject = Json.createReader(stringReader).readObject();
datasetVersion.setVersionNote(jsonObject.getString("deaccessionReason"));
String deaccessionForwardURL = jsonObject.getString("deaccessionForwardURL", null);
if (deaccessionForwardURL != null) {
try {
datasetVersion.setArchiveNote(deaccessionForwardURL);
} catch (IllegalArgumentException iae) {
return error(Response.Status.BAD_REQUEST, "Invalid deaccession forward URL: " + iae.getMessage());
pdurbin marked this conversation as resolved.
Show resolved Hide resolved
}
}
execCommand(new DeaccessionDatasetVersionCommand(req, datasetVersion, false));
return ok("Dataset " + datasetId + " deaccessioned for version " + versionId);
} catch (JsonParsingException jpe) {
return error(Response.Status.BAD_REQUEST, "Error parsing Json: " + jpe.getMessage());
}
}, getRequestUser(crc));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import edu.harvard.iq.dataverse.authorization.groups.impl.ipaddress.ip.IpAddress;
import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;
import edu.harvard.iq.dataverse.dataaccess.DataAccess;

import static edu.harvard.iq.dataverse.api.ApiConstants.DS_VERSION_DRAFT;
import static edu.harvard.iq.dataverse.dataaccess.DataAccess.getStorageIO;
import edu.harvard.iq.dataverse.dataaccess.StorageIO;
import edu.harvard.iq.dataverse.dataaccess.ImageThumbConverter;
Expand Down Expand Up @@ -580,10 +582,10 @@ public static String getLicenseURI(DatasetVersion dsv) {
// Return the URI
// For standard licenses, just return the stored URI
return (license != null) ? license.getUri().toString()
// For custom terms, construct a URI with :draft or the version number in the URI
// For custom terms, construct a URI with draft version constant or the version number in the URI
: (dsv.getVersionState().name().equals("DRAFT")
? dsv.getDataverseSiteUrl()
+ "/api/datasets/:persistentId/versions/:draft/customlicense?persistentId="
+ "/api/datasets/:persistentId/versions/" + DS_VERSION_DRAFT + "/customlicense?persistentId="
+ dsv.getDataset().getGlobalId().asString()
: dsv.getDataverseSiteUrl() + "/api/datasets/:persistentId/versions/" + dsv.getVersionNumber()
+ "." + dsv.getMinorVersionNumber() + "/customlicense?persistentId="
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,30 @@

/**
* Get the latest version of a dataset a user can view.
*
* @author Naomi
*/
// No permission needed to view published dvObjects
@RequiredPermissions({})
public class GetLatestAccessibleDatasetVersionCommand extends AbstractCommand<DatasetVersion>{
public class GetLatestAccessibleDatasetVersionCommand extends AbstractCommand<DatasetVersion> {
private final Dataset ds;
private final boolean includeDeaccessioned;

public GetLatestAccessibleDatasetVersionCommand(DataverseRequest aRequest, Dataset anAffectedDataset) {
this(aRequest, anAffectedDataset, false);
}

public GetLatestAccessibleDatasetVersionCommand(DataverseRequest aRequest, Dataset anAffectedDataset, boolean includeDeaccessioned) {
super(aRequest, anAffectedDataset);
ds = anAffectedDataset;
this.includeDeaccessioned = includeDeaccessioned;
}

@Override
public DatasetVersion execute(CommandContext ctxt) throws CommandException {

if (ds.getLatestVersion().isDraft() && ctxt.permissions().requestOn(getRequest(), ds).has(Permission.ViewUnpublishedDataset)) {
return ctxt.engine().submit(new GetDraftDatasetVersionCommand(getRequest(), ds));
}

return ctxt.engine().submit(new GetLatestPublishedDatasetVersionCommand(getRequest(), ds));

return ctxt.engine().submit(new GetLatestPublishedDatasetVersionCommand(getRequest(), ds, includeDeaccessioned));
}



}
Loading