Skip to content

Commit 78e8958

Browse files
KasinhouMatus Kasakmilanmajchrak
authored
ZCU-PUB/SWORDv2 - Cannot update bitstream of archived Item (#944)
* Using for instead of Iterator in removeBundle * Added a test to test file change in the Item * Use a default value for the plugin.single.org.dspace.sword2.WorkflowManager * Added a doc why we did that change --------- Co-authored-by: Matus Kasak <matus.kasak@dataquest.sk> Co-authored-by: milanmajchrak <milan.majchrak@dataquest.sk>
1 parent 66af883 commit 78e8958

2 files changed

Lines changed: 60 additions & 6 deletions

File tree

dspace-server-webapp/src/test/java/org/dspace/app/sword2/Swordv2IT.java

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import static org.junit.Assert.assertEquals;
1414
import static org.junit.Assert.assertNotNull;
1515

16+
import java.io.InputStream;
1617
import java.nio.file.Path;
1718
import java.sql.SQLException;
1819
import java.util.List;
@@ -620,5 +621,54 @@ public void statementTest() throws Exception {
620621
assertThat(response.getBody(),
621622
containsString("<category term=\"http://dspace.org/state/archived\""));
622623
}
623-
}
624624

625+
@Test
626+
public void updateFileTest() throws Exception {
627+
context.turnOffAuthorisationSystem();
628+
// Create all content as the SAME EPERSON we will use to authenticate on this endpoint.
629+
// THIS IS REQUIRED as the /statements endpoint will only show YOUR ITEM SUBMISSIONS.
630+
context.setCurrentUser(eperson);
631+
// Create a top level community and one Collection
632+
parentCommunity = CommunityBuilder.createCommunity(context)
633+
.withName("Parent Community")
634+
.build();
635+
Collection collection = CollectionBuilder.createCollection(context, parentCommunity)
636+
.withName("Test SWORDv2 Collection")
637+
.build();
638+
639+
// Add one Item into that Collection.
640+
InputStream pdf = getClass().getResourceAsStream("simple-article.pdf");
641+
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, collection)
642+
.withTitle("Test WorkspaceItem")
643+
.withIssueDate("2017-10-17")
644+
.withFulltext("simple-article.pdf", "/local/path/simple-article.pdf", pdf)
645+
.build();
646+
Item item = witem.getItem();
647+
648+
// Above changes MUST be committed to the database for SWORDv2 to see them.
649+
context.commit();
650+
context.restoreAuthSystemState();
651+
652+
String editLink = getURL(MEDIA_RESOURCE_PATH + "/" + item.getID().toString());
653+
// Load the ZIP file from the filesystem
654+
FileSystemResource zipFile = new FileSystemResource(
655+
Path.of("src", "test", "resources",
656+
"org", "dspace", "app", "sword2", "example.zip").toFile()
657+
);
658+
659+
// Set up headers
660+
HttpHeaders headers = new HttpHeaders();
661+
headers.setBasicAuth(admin.getEmail(), password);
662+
headers.setContentType(MediaType.valueOf("application/zip"));
663+
headers.setContentDisposition(ContentDisposition.attachment().filename("example.zip").build());
664+
665+
RequestEntity<FileSystemResource> request = RequestEntity
666+
.put(editLink)
667+
.headers(headers)
668+
.body(zipFile);
669+
ResponseEntity<String> response = responseAsString(request);
670+
671+
// Expect a 200 response with ATOM feed content returned
672+
assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
673+
}
674+
}

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.io.IOException;
1111
import java.sql.SQLException;
1212
import java.text.SimpleDateFormat;
13+
import java.util.ArrayList;
1314
import java.util.Date;
1415
import java.util.Iterator;
1516
import java.util.List;
@@ -43,14 +44,17 @@ public void removeBundle(Context context, Item item, String name)
4344
throws SQLException, AuthorizeException, IOException {
4445
boolean keep = configurationService
4546
.getBooleanProperty("swordv2-server.versions.keep");
46-
Iterator<Bundle> bundles = item.getBundles().iterator();
47-
while (bundles.hasNext()) {
48-
Bundle b = bundles.next();
47+
// Add the bundle to the list of bundles to remove because the method `this.removeBundle`
48+
// modifies the item's bundles, which can cause a ConcurrentModificationException.
49+
List<Bundle> bundlesToRemove = new ArrayList<>();
50+
for (Bundle b : item.getBundles()) {
4951
if (name.equals(b.getName())) {
50-
bundles.remove();
51-
this.removeBundle(context, item, b, keep);
52+
bundlesToRemove.add(b);
5253
}
5354
}
55+
for (Bundle b : bundlesToRemove) {
56+
this.removeBundle(context, item, b, keep);
57+
}
5458
}
5559

5660
public void removeBundle(Context context, Item item, Bundle source)

0 commit comments

Comments
 (0)