Skip to content
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
3 changes: 3 additions & 0 deletions doc/release-notes/12512-file-citation-version.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## API Updates

- When downloading a file citation it is now possible to specify the version of the dataset. See [the guides](https://guides.dataverse.org/en/6.13/api/dataaccess.html#citation-get-citation-in-other-formats) and #12512.
6 changes: 5 additions & 1 deletion doc/sphinx-guides/source/api/dataaccess.rst
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,12 @@ Usage example:
export SERVER_URL=https://demo.dataverse.org
export DATAFILE_ID=99
export FORMAT=EndNote
export VERSION=1.0
export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

curl -H "X-Dataverse-key:$API_TOKEN" "$SERVER_URL/api/access/datafile/$DATAFILE_ID/citation/$FORMAT?version=$VERSION"

curl "$SERVER_URL/api/access/datafile/$DATAFILE_ID/citation/$FORMAT"
The ``version`` query parameter is optional. It will default to ``:latest-published``. See :ref:`dataset-version-specifiers` for the list of possible values. If you request a draft, an API token with access must be provided.

.. _data-variable-metadata-access:

Expand Down
22 changes: 20 additions & 2 deletions src/main/java/edu/harvard/iq/dataverse/api/Access.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ public Response datafileCitation(@Context ContainerRequestContext crc,
@Parameter(description = "Data file id or persistent identifier.", required = true)
@PathParam("fileId") String fileId,
@Parameter(description = "Citation format to return.")
@PathParam("format") String formatString) {
@PathParam("format") String formatString,
@Parameter(description = "Dataset version, such as 1.0, :draft, :latest, or :latest-published. If omitted, uses :latest-published.", required = false)
@QueryParam("version") String version) {

DataCitation.Format format = DataCitation.getFormat(formatString);
if (format == null) {
Expand All @@ -158,7 +160,23 @@ public Response datafileCitation(@Context ContainerRequestContext crc,
// This will throw a ForbiddenException if access isn't authorized:
checkAuthorization(req.getUser(), df);

String dataCitationFormatted = (new DataCitation(df.getFileMetadata())).toString(format, true, false);
// Default to latest file metadata.
FileMetadata fileMetadata = df.getFileMetadata();
if (version != null) {
try {
DatasetVersion datasetVersion = getDatasetVersionFromVersion(crc, df.getOwner().getId().toString(), version);
if (datasetVersion == null) {
return badRequest("Dataset version not found: " + version);
}
fileMetadata = dataFileService.findFileMetadataByDatasetVersionIdAndDataFileId(datasetVersion.getId(), df.getId());
if (fileMetadata == null) {
return badRequest("File not found in dataset version: " + version);
}
} catch (WrappedResponse wr) {
return wr.getResponse();
}
}
String dataCitationFormatted = (new DataCitation(fileMetadata)).toString(format, true, false);

return Response.ok().type(DataCitation.getCitationFormatMediaType(format, true)).entity(dataCitationFormatted).build();
}
Expand Down
62 changes: 62 additions & 0 deletions src/test/java/edu/harvard/iq/dataverse/api/FilesIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -4284,6 +4284,68 @@ public void testGetFileCitationFormatted() {
.statusCode(OK.getStatusCode());
}

@Test
public void testGetFileCitationFormattedWithVersion() {
Response createUser = UtilIT.createRandomUser();
createUser.then().statusCode(OK.getStatusCode());
String apiToken = UtilIT.getApiTokenFromResponse(createUser);

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

Response createDataset = UtilIT.createRandomDatasetViaNativeApi(dataverseAlias, apiToken);
createDataset.then().statusCode(CREATED.getStatusCode());

Integer datasetId = createDataset.jsonPath().getInt("data.id");

Response uploadFile = UtilIT.uploadFileViaNative(datasetId.toString(),
"src/test/resources/images/coffeeshop.png", JsonUtil.createObjectBuilder().build(), apiToken);
uploadFile.then().statusCode(OK.getStatusCode());

String fileId = uploadFile.jsonPath().getString("data.files[0].dataFile.id");

UtilIT.publishDataverseViaNativeApi(dataverseAlias, apiToken).then().statusCode(OK.getStatusCode());
UtilIT.publishDatasetViaNativeApi(datasetId, "major", apiToken).then().statusCode(OK.getStatusCode());
UtilIT.updateFileMetadata(fileId, "{\"label\":\"renamed.png\"}", apiToken)
.then().statusCode(OK.getStatusCode());

// The same file has different metadata in the published version and the draft.
UtilIT.getFileCitationFormat(fileId, "EndNote", null, "1.0").then()
.statusCode(OK.getStatusCode()).body(containsString("<custom1>coffeeshop.png</custom1>"));
UtilIT.getFileCitationFormat(fileId, "EndNote", apiToken, ":draft").then()
.statusCode(OK.getStatusCode()).body(containsString("<custom1>renamed.png</custom1>"));
UtilIT.getFileCitationFormat(fileId, "EndNote", apiToken, ":latest").then()
.statusCode(OK.getStatusCode()).body(containsString("<custom1>renamed.png</custom1>"));
// No API token given so the published filename is shown
UtilIT.getFileCitationFormat(fileId, "EndNote", null, ":latest").then()
.statusCode(OK.getStatusCode()).body(containsString("<custom1>coffeeshop.png</custom1>"));
UtilIT.getFileCitationFormat(fileId, "EndNote", apiToken, ":latest-published").then()
.statusCode(OK.getStatusCode()).body(containsString("<custom1>coffeeshop.png</custom1>"));
UtilIT.getFileCitationFormat(fileId, "EndNote", null, ":draft").then()
.statusCode(UNAUTHORIZED.getStatusCode());

UtilIT.publishDatasetViaNativeApi(datasetId, "minor", apiToken).then().statusCode(OK.getStatusCode());
UtilIT.getFileCitationFormat(fileId, "EndNote", null, "1.1").then()
.statusCode(OK.getStatusCode()).body(containsString("<custom1>renamed.png</custom1>"));
// Historical citations still use the original file metadata after another release.
UtilIT.getFileCitationFormat(fileId, "EndNote", null, "1.0").then()
.statusCode(OK.getStatusCode()).body(containsString("<custom1>coffeeshop.png</custom1>"));
UtilIT.getFileCitationFormat(fileId, "RIS", null, "1.0").then()
.statusCode(OK.getStatusCode()).body(containsString("C1 - coffeeshop.png"));
UtilIT.getFileCitationFormat(fileId, "EndNote", apiToken, "666.0").then()
.statusCode(BAD_REQUEST.getStatusCode());
UtilIT.getFileCitationFormat(fileId, "EndNote", apiToken, "invalid").then()
.statusCode(BAD_REQUEST.getStatusCode());

Response uploadNewFile = UtilIT.uploadFileViaNative(datasetId.toString(),
"src/main/webapp/resources/images/dataverseproject.png", JsonUtil.createObjectBuilder().build(), apiToken);
uploadNewFile.then().statusCode(OK.getStatusCode());
String newFileId = uploadNewFile.jsonPath().getString("data.files[0].dataFile.id");
UtilIT.getFileCitationFormat(newFileId, "EndNote", apiToken, "1.0").then()
.statusCode(BAD_REQUEST.getStatusCode()).body("message", equalTo("File not found in dataset version: 1.0"));
}

// This test is disabled because it is only compatible with the containerized development environment and would cause the Jenkins job to fail.
@Test
@Disabled
Expand Down
7 changes: 7 additions & 0 deletions src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -1508,10 +1508,17 @@ static Response getFileData(String fileId, String apiToken, String datasetVersio
}

static Response getFileCitationFormat(String dataFileId, String format, String apiToken) {
return getFileCitationFormat(dataFileId, format, apiToken, null);
}

static Response getFileCitationFormat(String dataFileId, String format, String apiToken, String version) {
RequestSpecification request = given();
if (apiToken != null) {
request.header(API_TOKEN_HTTP_HEADER, apiToken);
}
if (version != null) {
request.queryParam("version", version);
}
return request.get("/api/access/datafile/" + dataFileId + "/citation/" + format);
}

Expand Down
Loading