Skip to content

Commit

Permalink
fix: replace PATCH request on /metadata now supports multiple values
Browse files Browse the repository at this point in the history
  • Loading branch information
MMilosz committed Aug 21, 2024
1 parent cbea61c commit 16cb7da
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand Down Expand Up @@ -50,32 +52,46 @@ private DSpaceObjectMetadataPatchUtils() {
* @return MetadataValueRest extracted from json in operation value
*/
protected MetadataValueRest extractMetadataValueFromOperation(Operation operation) {
MetadataValueRest metadataValue = null;
return extractMetadataValueListFromOperation(operation).get(0);
}

/**
* Extract metadataValue from Operation by parsing the json and mapping it to a MetadataValueRest
* @param operation Operation whose value is begin parsed
* @return MetadataValueRest extracted from json in operation value
*/
protected List<MetadataValueRest> extractMetadataValueListFromOperation(Operation operation) {
List<MetadataValueRest> metadataValueList = new ArrayList<>();
try {
if (operation.getValue() != null) {
if (operation.getValue() instanceof JsonValueEvaluator) {
JsonNode valueNode = ((JsonValueEvaluator) operation.getValue()).getValueNode();
if (valueNode.isArray()) {
metadataValue = objectMapper.treeToValue(valueNode.get(0), MetadataValueRest.class);
for (JsonNode node : valueNode) {
MetadataValueRest metadataValue = objectMapper.treeToValue(node, MetadataValueRest.class);
metadataValueList.add(metadataValue);
}
} else {
metadataValue = objectMapper.treeToValue(valueNode, MetadataValueRest.class);
MetadataValueRest metadataValue = objectMapper.treeToValue(valueNode, MetadataValueRest.class);
metadataValueList.add(metadataValue);
}
}
if (operation.getValue() instanceof String) {
String valueString = (String) operation.getValue();
metadataValue = new MetadataValueRest();
MetadataValueRest metadataValue = new MetadataValueRest();
metadataValue.setValue(valueString);
metadataValueList.add(metadataValue);
}
}
} catch (IOException e) {
throw new DSpaceBadRequestException("IOException in " +
"DspaceObjectMetadataOperation.extractMetadataValueFromOperation trying to map json from " +
"operation.value to MetadataValue class.", e);
"DspaceObjectMetadataOperation.extractMetadataValueFromOperation trying to map json from " +
"operation.value to MetadataValue class.", e);
}
if (metadataValue == null) {
if (metadataValueList.isEmpty()) {
throw new DSpaceBadRequestException("Could not extract MetadataValue Object from Operation");
}
return metadataValue;
return metadataValueList;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ public R perform(Context context, R resource, Operation operation) throws SQLExc
String[] partsOfPath = operation.getPath().split("/");
// Index of md being patched
String indexInPath = (partsOfPath.length > 3) ? partsOfPath[3] : null;
MetadataValueRest metadataValueToReplace = metadataPatchUtils.extractMetadataValueFromOperation(operation);
List<MetadataValueRest> metadataValueToReplace =
metadataPatchUtils.extractMetadataValueListFromOperation(operation);
// Property of md being altered
String propertyOfMd = metadataPatchUtils.extractPropertyOfMdFromPath(partsOfPath);
String newValueMdAttribute = metadataPatchUtils.extractNewValueOfMd(operation);
Expand Down Expand Up @@ -78,6 +79,29 @@ public R perform(Context context, R resource, Operation operation) throws SQLExc
*/
private void replace(Context context, DSpaceObject dso, DSpaceObjectService dsoService, MetadataField metadataField,
MetadataValueRest metadataValue, String index, String propertyOfMd, String valueMdProperty) {
replace(context, dso, dsoService, metadataField, List.of(metadataValue), index, propertyOfMd, valueMdProperty);
}

/**
* Replaces metadata in the dso; 4 cases:
* * - If we replace everything: clears all metadata
* * - If we replace for a single field: clearMetadata on the field & add the new ones
* * - A single existing metadata value:
* * Retrieve the metadatavalue object & make alterations directly on this object
* * - A single existing metadata property:
* * Retrieve the metadatavalue object & make alterations directly on this object
* @param context context patch is being performed in
* @param dso dso being patched
* @param dsoService service doing the patch in db
* @param metadataField possible md field being patched (if null all md gets cleared)
* @param metadataValue list of values of md element
* @param index possible index of md being replaced
* @param propertyOfMd possible property of md being replaced
* @param valueMdProperty possible new value of property of md being replaced
*/
private void replace(Context context, DSpaceObject dso, DSpaceObjectService dsoService, MetadataField metadataField,
List<MetadataValueRest> metadataValue, String index, String propertyOfMd,
String valueMdProperty) {
// replace entire set of metadata
if (metadataField == null) {
this.replaceAllMetadata(context, dso, dsoService);
Expand All @@ -90,8 +114,8 @@ private void replace(Context context, DSpaceObject dso, DSpaceObjectService dsoS
return;
}
// replace single existing metadata value
if (propertyOfMd == null) {
this.replaceSingleMetadataValue(dso, dsoService, metadataField, metadataValue, index);
if (propertyOfMd == null && !metadataValue.isEmpty()) {
this.replaceSingleMetadataValue(dso, dsoService, metadataField, metadataValue.get(0), index);
return;
}
// replace single property of exiting metadata value
Expand Down Expand Up @@ -119,16 +143,18 @@ private void replaceAllMetadata(Context context, DSpaceObject dso, DSpaceObjectS
* @param dso dso being patched
* @param dsoService service doing the patch in db
* @param metadataField md field being patched
* @param metadataValue value of md element
* @param metadataValueList value of md element
*/
private void replaceMetadataFieldMetadata(Context context, DSpaceObject dso, DSpaceObjectService dsoService,
MetadataField metadataField, MetadataValueRest metadataValue) {
MetadataField metadataField, List<MetadataValueRest> metadataValueList) {
try {
dsoService.clearMetadata(context, dso, metadataField.getMetadataSchema().getName(),
metadataField.getElement(), metadataField.getQualifier(), Item.ANY);
dsoService.addAndShiftRightMetadata(context, dso, metadataField.getMetadataSchema().getName(),
for (MetadataValueRest metadataValue : metadataValueList) {
dsoService.addAndShiftRightMetadata(context, dso, metadataField.getMetadataSchema().getName(),
metadataField.getElement(), metadataField.getQualifier(), metadataValue.getLanguage(),
metadataValue.getValue(), metadataValue.getAuthority(), metadataValue.getConfidence(), -1);
}
} catch (SQLException e) {
throw new DSpaceBadRequestException("SQLException in DspaceObjectMetadataOperation.replace trying to " +
"remove and replace metadata from dso.", e);
Expand Down

0 comments on commit 16cb7da

Please sign in to comment.