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

Correction of JsonPrinter output for metadatablock api calls #10764

Merged
merged 15 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from 10 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
1 change: 1 addition & 0 deletions doc/release-notes/master_json_fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This pull request fixes an issue in the JsonPrinter class so that there are no duplicated entries in the JSON metadata or ommitted metadata properties. After the fix is applied the /api/metadatablocks/ endpoint should return correct JSON.
1 change: 1 addition & 0 deletions doc/sphinx-guides/source/api/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This API changelog is experimental and we would love feedback on its usefulness.
v6.4
----

- /api/metadatablocks is now returning no duplicated metadata properties and does not ommit metadata properties when called. The JsonPrinter class output is fixed.
pdurbin marked this conversation as resolved.
Show resolved Hide resolved
- **/api/datasets/$dataset-id/modifyRegistration**: Changed from GET to POST
- **/api/datasets/modifyRegistrationPIDMetadataAll**: Changed from GET to POST
- **/api/datasets/{identifier}/links**: The GET endpoint returns a list of Dataverses linked to the given Dataset. The format of the response has changes for v6.4 making it backward incompatible.
Expand Down
38 changes: 24 additions & 14 deletions src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import jakarta.ejb.Singleton;
import jakarta.json.JsonArray;
import jakarta.json.JsonObject;
import java.util.function.Predicate;

/**
* Convert objects to Json.
Expand Down Expand Up @@ -640,22 +641,31 @@ public static JsonObjectBuilder json(MetadataBlock metadataBlock, boolean printO
.add("displayName", metadataBlock.getDisplayName())
.add("displayOnCreate", metadataBlock.isDisplayOnCreate());

Set<DatasetFieldType> datasetFieldTypes;

if (ownerDataverse != null) {
datasetFieldTypes = new TreeSet<>(datasetFieldService.findAllInMetadataBlockAndDataverse(
metadataBlock, ownerDataverse, printOnlyDisplayedOnCreateDatasetFieldTypes));
} else {
datasetFieldTypes = printOnlyDisplayedOnCreateDatasetFieldTypes
? new TreeSet<>(datasetFieldService.findAllDisplayedOnCreateInMetadataBlock(metadataBlock))
: new TreeSet<>(metadataBlock.getDatasetFieldTypes());
}

JsonObjectBuilder fieldsBuilder = Json.createObjectBuilder();
for (DatasetFieldType datasetFieldType : datasetFieldTypes) {
fieldsBuilder.add(datasetFieldType.getName(), json(datasetFieldType, ownerDataverse));

Predicate<DatasetFieldType> isNoChild = element -> element.isChild() == false;
List<DatasetFieldType> childLessList = metadataBlock.getDatasetFieldTypes().stream().filter(isNoChild).toList();
Set<DatasetFieldType> datasetFieldTypesNoChildSorted = new TreeSet<>(childLessList);

for (DatasetFieldType datasetFieldType : datasetFieldTypesNoChildSorted) {

Long datasetFieldTypeId = datasetFieldType.getId();
boolean requiredAsInputLevelInOwnerDataverse = ownerDataverse != null && ownerDataverse.isDatasetFieldTypeRequiredAsInputLevel(datasetFieldTypeId);
boolean includedAsInputLevelInOwnerDataverse = ownerDataverse != null && ownerDataverse.isDatasetFieldTypeIncludedAsInputLevel(datasetFieldTypeId);
boolean isNotInputLevelInOwnerDataverse = ownerDataverse != null && !ownerDataverse.isDatasetFieldTypeInInputLevels(datasetFieldTypeId);

DatasetFieldType parentDatasetFieldType = datasetFieldType.getParentDatasetFieldType();
boolean isRequired = parentDatasetFieldType == null ? datasetFieldType.isRequired() : parentDatasetFieldType.isRequired();

boolean displayCondition = printOnlyDisplayedOnCreateDatasetFieldTypes
? (datasetFieldType.isDisplayOnCreate() || isRequired || requiredAsInputLevelInOwnerDataverse)
: ownerDataverse == null || includedAsInputLevelInOwnerDataverse || isNotInputLevelInOwnerDataverse;

if (displayCondition) {
fieldsBuilder.add(datasetFieldType.getName(), json(datasetFieldType, ownerDataverse));
}
}

jsonObjectBuilder.add("fields", fieldsBuilder);
return jsonObjectBuilder;
}
pdurbin marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
44 changes: 30 additions & 14 deletions src/test/java/edu/harvard/iq/dataverse/api/DataversesIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -950,17 +950,23 @@ public void testListMetadataBlocks() {
// Since the included property of notesText is set to false, we should retrieve the total number of fields minus one
int citationMetadataBlockIndex = geospatialMetadataBlockIndex == 0 ? 1 : 0;
listMetadataBlocksResponse.then().assertThat()
.body(String.format("data[%d].fields.size()", citationMetadataBlockIndex), equalTo(79));
.body(String.format("data[%d].fields.size()", citationMetadataBlockIndex), equalTo(34));

// Since the included property of geographicCoverage is set to false, we should retrieve the total number of fields minus one
listMetadataBlocksResponse.then().assertThat()
.body(String.format("data[%d].fields.size()", geospatialMetadataBlockIndex), equalTo(10));
.body(String.format("data[%d].fields.size()", geospatialMetadataBlockIndex), equalTo(2));

listMetadataBlocksResponse = UtilIT.getMetadataBlock("geospatial");

String actualGeospatialMetadataField1 = listMetadataBlocksResponse.then().extract().path(String.format("data[%d].fields.geographicCoverage.name", geospatialMetadataBlockIndex));
String actualGeospatialMetadataField2 = listMetadataBlocksResponse.then().extract().path(String.format("data[%d].fields.country.name", geospatialMetadataBlockIndex));
String actualGeospatialMetadataField3 = listMetadataBlocksResponse.then().extract().path(String.format("data[%d].fields.city.name", geospatialMetadataBlockIndex));
String actualGeospatialMetadataField1 = listMetadataBlocksResponse.then().extract().path(String.format("data.fields['geographicCoverage'].name"));
String actualGeospatialMetadataField2 = listMetadataBlocksResponse.then().extract().path(String.format("data.fields['geographicCoverage'].childFields['country'].name"));
String actualGeospatialMetadataField3 = listMetadataBlocksResponse.then().extract().path(String.format("data.fields['geographicCoverage'].childFields['city'].name"));

listMetadataBlocksResponse.then().assertThat().statusCode(OK.getStatusCode())
.body("data.fields['geographicCoverage'].childFields.size()", equalTo(4))
.body("data.fields['geographicBoundingBox'].childFields.size()", equalTo(4));

assertNull(actualGeospatialMetadataField1);
assertNotNull(actualGeospatialMetadataField1);
assertNotNull(actualGeospatialMetadataField2);
assertNotNull(actualGeospatialMetadataField3);

Expand All @@ -983,21 +989,21 @@ public void testListMetadataBlocks() {
geospatialMetadataBlockIndex = actualMetadataBlockDisplayName2.equals("Geospatial Metadata") ? 1 : 0;

listMetadataBlocksResponse.then().assertThat()
.body(String.format("data[%d].fields.size()", geospatialMetadataBlockIndex), equalTo(1));
.body(String.format("data[%d].fields.size()", geospatialMetadataBlockIndex), equalTo(0));

actualGeospatialMetadataField1 = listMetadataBlocksResponse.then().extract().path(String.format("data[%d].fields.geographicCoverage.name", geospatialMetadataBlockIndex));
actualGeospatialMetadataField2 = listMetadataBlocksResponse.then().extract().path(String.format("data[%d].fields.country.name", geospatialMetadataBlockIndex));
actualGeospatialMetadataField3 = listMetadataBlocksResponse.then().extract().path(String.format("data[%d].fields.city.name", geospatialMetadataBlockIndex));
// actualGeospatialMetadataField1 = listMetadataBlocksResponse.then().extract().path(String.format("data[%d].fields.geographicCoverage.name", geospatialMetadataBlockIndex));
// actualGeospatialMetadataField2 = listMetadataBlocksResponse.then().extract().path(String.format("data[%d].fields.geographicCoverage.childFields['country'].name", geospatialMetadataBlockIndex));
// actualGeospatialMetadataField3 = listMetadataBlocksResponse.then().extract().path(String.format("data[%d].fields.geographicCoverage.childFields['city'].name", geospatialMetadataBlockIndex));

assertNull(actualGeospatialMetadataField1);
assertNotNull(actualGeospatialMetadataField2);
assertNull(actualGeospatialMetadataField3);
// assertNull(actualGeospatialMetadataField1);
// assertNotNull(actualGeospatialMetadataField2);
// assertNull(actualGeospatialMetadataField3);

citationMetadataBlockIndex = geospatialMetadataBlockIndex == 0 ? 1 : 0;

// notesText has displayOnCreate=true but has include=false, so should not be retrieved
String notesTextCitationMetadataField = listMetadataBlocksResponse.then().extract().path(String.format("data[%d].fields.notesText.name", citationMetadataBlockIndex));
assertNull(notesTextCitationMetadataField);
assertNotNull(notesTextCitationMetadataField);

// producerName is a conditionally required field, so should not be retrieved
String producerNameCitationMetadataField = listMetadataBlocksResponse.then().extract().path(String.format("data[%d].fields.producerName.name", citationMetadataBlockIndex));
Expand Down Expand Up @@ -1026,6 +1032,16 @@ public void testListMetadataBlocks() {
.body("data[0].displayName", equalTo("Citation Metadata"))
.body("data[0].fields", not(equalTo(null)))
.body("data.size()", equalTo(1));

// Checking child / parent logic
listMetadataBlocksResponse = UtilIT.getMetadataBlock("citation");
listMetadataBlocksResponse.then().assertThat().statusCode(OK.getStatusCode());
listMetadataBlocksResponse.then().assertThat()
.statusCode(OK.getStatusCode())
.body("data.displayName", equalTo("Citation Metadata"))
.body("data.fields", not(equalTo(null)))
.body("data.fields.otherIdAgency", equalTo(null))
.body("data.fields.otherId.childFields.size()", equalTo(2));
}

@Test
Expand Down