[CST-4039] Patch Add entire array with virtual values does not work

This commit is contained in:
Alessandro Martelli
2021-04-07 18:21:31 +02:00
parent 4d68fa4ad3
commit 5b90afab4e
5 changed files with 63 additions and 17 deletions

View File

@@ -1363,7 +1363,7 @@ prevent the generation of resource policy entry values with null dspace_object a
* Supports moving metadata by adding the metadata value or updating the place of the relationship * Supports moving metadata by adding the metadata value or updating the place of the relationship
*/ */
@Override @Override
public void moveSingleMetadataValue(Context context, Item dso, int place, MetadataValue rr) { protected void moveSingleMetadataValue(Context context, Item dso, int place, MetadataValue rr) {
if (rr instanceof RelationshipMetadataValue) { if (rr instanceof RelationshipMetadataValue) {
try { try {
//Retrieve the applicable relationship //Retrieve the applicable relationship

View File

@@ -368,7 +368,7 @@ public interface DSpaceObjectService<T extends DSpaceObject> {
String lang, String value) throws SQLException; String lang, String value) throws SQLException;
/** /**
* Add a single metadata field at the given place position. * Add a single metadata value at the given place position.
* *
* @param context DSpace context * @param context DSpace context
* @param dso DSpaceObject * @param dso DSpaceObject

View File

@@ -741,13 +741,4 @@ public interface ItemService
public List<MetadataValue> getMetadata(Item item, String schema, String element, String qualifier, public List<MetadataValue> getMetadata(Item item, String schema, String element, String qualifier,
String lang, boolean enableVirtualMetadata); String lang, boolean enableVirtualMetadata);
/**
*
* @param context DSpace context object
* @param item Item
* @param place new metadata position
* @param rr MetadataValue to move
*/
public void moveSingleMetadataValue(Context context, Item item, int place, MetadataValue rr);
} }

View File

@@ -14,6 +14,8 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.MetadataValueRest; import org.dspace.app.rest.model.MetadataValueRest;
import org.dspace.app.rest.model.patch.LateObjectEvaluator; import org.dspace.app.rest.model.patch.LateObjectEvaluator;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
@@ -76,6 +78,12 @@ import org.springframework.util.Assert;
*/ */
public class ItemMetadataValueAddPatchOperation extends MetadataValueAddPatchOperation<Item> { public class ItemMetadataValueAddPatchOperation extends MetadataValueAddPatchOperation<Item> {
/**
* log4j category
*/
private static final Logger log =
org.apache.logging.log4j.LogManager.getLogger(ItemMetadataValueAddPatchOperation.class);
@Autowired @Autowired
ItemService itemService; ItemService itemService;
@@ -154,20 +162,21 @@ public class ItemMetadataValueAddPatchOperation extends MetadataValueAddPatchOpe
// if a virtual value is present in the list, it must be present in preExistentRelationships too. // if a virtual value is present in the list, it must be present in preExistentRelationships too.
// (with this operator virtual value can only be moved or deleted). // (with this operator virtual value can only be moved or deleted).
// a not present virtual value will be discarded
int idx = 0; int idx = 0;
for (MetadataValueRest ll : list) { for (MetadataValueRest ll : list) {
if (StringUtils.startsWith(ll.getAuthority(), Constants.VIRTUAL_AUTHORITY_PREFIX)) { if (StringUtils.startsWith(ll.getAuthority(), Constants.VIRTUAL_AUTHORITY_PREFIX)) {
Optional<MetadataValue> preExistentMvr = preExistentMetadata.stream().filter(mvr -> Optional<MetadataValue> preExistentMv = preExistentMetadata.stream().filter(mvr ->
StringUtils.equals(ll.getAuthority(), mvr.getAuthority())).findFirst(); StringUtils.equals(ll.getAuthority(), mvr.getAuthority())).findFirst();
if (!preExistentMvr.isPresent()) { if (!preExistentMv.isPresent()) {
idx++; throw new UnprocessableEntityException(
continue; "Relationship with authority=" + ll.getAuthority() + " not found");
} }
this.itemService.moveSingleMetadataValue(context, source, idx, preExistentMvr.get()); final RelationshipMetadataValue rmv = (RelationshipMetadataValue) preExistentMv.get();
final Relationship rel = preExistentRelationships.get(rmv.getRelationshipId());
this.updateRelationshipPlace(context, source, idx, rel);
} else { } else {
getDSpaceObjectService() getDSpaceObjectService()
@@ -201,6 +210,22 @@ public class ItemMetadataValueAddPatchOperation extends MetadataValueAddPatchOpe
return relId; return relId;
} }
private void updateRelationshipPlace(Context context, Item dso, int place, Relationship rs) {
try {
if (rs.getLeftItem() == dso) {
rs.setLeftPlace(place);
} else {
rs.setRightPlace(place);
}
relationshipService.update(context, rs);
} catch (Exception e) {
//should not occur, otherwise metadata can't be updated either
log.error("An error occurred while moving " + rs.getID() + " for item " + dso.getID(), e);
}
}
@Override @Override
protected ItemService getDSpaceObjectService() { protected ItemService getDSpaceObjectService() {
return itemService; return itemService;

View File

@@ -1191,6 +1191,36 @@ public class PatchMetadataIT extends AbstractEntityIntegrationTest {
} }
/**
* This test will overwrite all authors (dc.contributor.author) of a workspace publication's "traditionalpageone"
* section using a PATCH add with an array composed by only a not existent virtual metadata.
*/
@Test
public void patchAddAllAuthorsOnTraditionalPageNotExistentRelationTest() throws Exception {
initPersonPublicationWorkspace();
List<Operation> ops = new ArrayList<Operation>();
List<MetadataValueRest> value = new ArrayList<MetadataValueRest>();
MetadataValueRest mrv = new MetadataValueRest();
value.add(mrv);
mrv.setValue("Dumbar, John");
mrv.setAuthority("virtual::" + Integer.MAX_VALUE);
AddOperation add = new AddOperation("/sections/traditionalpageone/dc.contributor.author", value);
ops.add(add);
String patchBody = getPatchContent(ops);
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(patch("/api/submission/workspaceitems/" + publicationItem.getID())
.content(patchBody)
.contentType(javax.ws.rs.core.MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isUnprocessableEntity());
}
/** /**
* This method moves an author (dc.contributor.author) within a workspace publication's "traditionalpageone" * This method moves an author (dc.contributor.author) within a workspace publication's "traditionalpageone"
* section from position "from" to "path" using a PATCH request and verifies the order of the authors within the * section from position "from" to "path" using a PATCH request and verifies the order of the authors within the