Skip to content

Commit 15bfb13

Browse files
jr-rkclaude
andcommitted
fix(swordv2): guard against double-delete in ContainerManagerDSpace.removeItem
Deleting a SWORDv2 item with WorkflowManagerDefault deleted the item twice and the second itemService.delete() threw. The fix -- deleteAll on the workspace path plus an isItemAlreadyDeleted guard before the final delete -- was present on dtq-dev via f79e704 and reverted by the #1031 7.6.5 upgrade merge, while the two Swordv2IT tests that cover it were left behind. This restores the reverted delta (identical to customer/zcu-pub 66af883). Not taken from zcu-pub: its SwordUrlManager changes -- dtq-dev is ahead there. Port of dataquest-dev/dspace-customers#903 (item 3). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 6114281 commit 15bfb13

1 file changed

Lines changed: 26 additions & 3 deletions

File tree

dspace-swordv2/src/main/java/org/dspace/sword2/ContainerManagerDSpace.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.util.List;
1414
import java.util.Map;
1515
import java.util.TreeMap;
16+
import java.util.UUID;
1617

1718
import org.apache.logging.log4j.Logger;
1819
import org.dspace.authorize.AuthorizeException;
@@ -25,6 +26,7 @@
2526
import org.dspace.core.Constants;
2627
import org.dspace.core.Context;
2728
import org.dspace.core.LogHelper;
29+
import org.dspace.event.Event;
2830
import org.dspace.workflow.WorkflowItem;
2931
import org.dspace.workflow.WorkflowItemService;
3032
import org.dspace.workflow.factory.WorkflowServiceFactory;
@@ -755,14 +757,19 @@ protected void doContainerDelete(SwordContext swordContext, Item item,
755757
WorkflowTools wft = new WorkflowTools();
756758
if (wft.isItemInWorkspace(swordContext.getContext(), item)) {
757759
WorkspaceItem wsi = wft.getWorkspaceItem(context, item);
758-
workspaceItemService.deleteWrapper(context, wsi);
760+
workspaceItemService.deleteAll(context, wsi);
761+
// the item is deleted in the above call
759762
} else if (wft.isItemInWorkflow(context, item)) {
760763
WorkflowItem wfi = wft.getWorkflowItem(context, item);
761764
workflowItemService.deleteWrapper(context, wfi);
762765
}
763766

764-
// then delete the item
765-
itemService.delete(context, item);
767+
// then delete the item, but only if it hasn't already been deleted by the methods above.
768+
// the delete method is called in `workspaceItemService.deleteAll(context, wsi);`,
769+
// so it should not be called again here, as that would throw an exception.
770+
if (!isItemAlreadyDeleted(context, item.getID())) {
771+
itemService.delete(context, item);
772+
}
766773
} catch (SQLException | IOException e) {
767774
throw new DSpaceSwordException(e);
768775
} catch (AuthorizeException e) {
@@ -788,4 +795,20 @@ private Item getDSpaceTarget(Context context, String editUrl,
788795

789796
return item;
790797
}
798+
799+
/**
800+
* Check if the item is already deleted in the context.
801+
*/
802+
private boolean isItemAlreadyDeleted(Context context, UUID itemUUID) {
803+
if (context.getEvents() == null) {
804+
return false;
805+
}
806+
807+
for (Event event : context.getEvents()) {
808+
if (event.getEventType() == Event.DELETE && event.getSubjectID().equals(itemUUID)) {
809+
return true;
810+
}
811+
}
812+
return false;
813+
}
791814
}

0 commit comments

Comments
 (0)