From 645f6b66c93d4cc101e63af0ac00da3bfa6b66ae Mon Sep 17 00:00:00 2001 From: Raf Ponsaerts Date: Fri, 26 Jun 2020 09:32:50 +0200 Subject: [PATCH 001/179] [Task 71502] implemented tests that prove that deleting an item with a relationship of min cardinality greater than 1 fails --- .../dspace/app/rest/ItemRestRepositoryIT.java | 123 ++++++++++++++++++ .../rest/builder/WorkspaceItemBuilder.java | 4 + 2 files changed, 127 insertions(+) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java index 0c96d24288..ddfd63e446 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java @@ -37,8 +37,11 @@ import org.dspace.app.rest.builder.BitstreamBuilder; import org.dspace.app.rest.builder.CollectionBuilder; import org.dspace.app.rest.builder.CommunityBuilder; import org.dspace.app.rest.builder.EPersonBuilder; +import org.dspace.app.rest.builder.EntityTypeBuilder; import org.dspace.app.rest.builder.GroupBuilder; import org.dspace.app.rest.builder.ItemBuilder; +import org.dspace.app.rest.builder.RelationshipBuilder; +import org.dspace.app.rest.builder.RelationshipTypeBuilder; import org.dspace.app.rest.builder.ResourcePolicyBuilder; import org.dspace.app.rest.builder.WorkspaceItemBuilder; import org.dspace.app.rest.matcher.BitstreamMatcher; @@ -55,7 +58,10 @@ import org.dspace.app.rest.test.MetadataPatchSuite; import org.dspace.content.Bitstream; import org.dspace.content.Collection; import org.dspace.content.Community; +import org.dspace.content.EntityType; import org.dspace.content.Item; +import org.dspace.content.Relationship; +import org.dspace.content.RelationshipType; import org.dspace.content.WorkspaceItem; import org.dspace.content.service.CollectionService; import org.dspace.eperson.EPerson; @@ -2698,5 +2704,122 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { } + @Test + public void deleteItemWithMinRelationshipsTest() throws Exception { + context.turnOffAuthorisationSystem(); + + //** GIVEN ** + //1. A community with one collection. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection col1 = CollectionBuilder + .createCollection(context, parentCommunity).withName("Collection 1").build(); + + Item author1 = ItemBuilder.createItem(context, col1) + .withTitle("Author1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withPersonIdentifierLastName("Smith") + .withPersonIdentifierFirstName("Donald") + .withRelationshipType("Person") + .build(); + + Item author2 = ItemBuilder.createItem(context, col1) + .withTitle("Author2") + .withIssueDate("2016-02-13") + .withAuthor("Smith, Maria") + .withRelationshipType("Person") + .build(); + + Item publication1 = ItemBuilder.createItem(context, col1) + .withTitle("Publication1") + .withAuthor("Testy, TEst") + .withIssueDate("2015-01-01") + .withRelationshipType("Publication") + .build(); + + EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + EntityType person = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); + + + RelationshipType isAuthorOfPublication = RelationshipTypeBuilder.createRelationshipTypeBuilder(context, publication, person, "isAuthorOfPublication", + "isPublicationOfAuthor", 2, null, 0, + null).withCopyToLeft(false).withCopyToRight(true).build(); + + Relationship relationship1 = RelationshipBuilder.createRelationshipBuilder(context, publication1, author1, isAuthorOfPublication).build(); + Relationship relationship2 = RelationshipBuilder.createRelationshipBuilder(context, publication1, author2, isAuthorOfPublication).build(); + + context.restoreAuthSystemState(); + + String token = getAuthToken(admin.getEmail(), password); + + getClient(token).perform(delete("/api/core/relationships/" + relationship1.getID())) + .andExpect(status().is(400)); + //Delete public item + getClient(token).perform(delete("/api/core/items/" + publication1.getID())) + .andExpect(status().is(204)); + + + + } + + @Test + public void deleteWorkspaceItemWithMinRelationshipsTest() throws Exception { + context.turnOffAuthorisationSystem(); + + //** GIVEN ** + //1. A community with one collection. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection col1 = CollectionBuilder + .createCollection(context, parentCommunity).withName("Collection 1").build(); + + Item author1 = ItemBuilder.createItem(context, col1) + .withTitle("Author1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withPersonIdentifierLastName("Smith") + .withPersonIdentifierFirstName("Donald") + .withRelationshipType("Person") + .build(); + + Item author2 = ItemBuilder.createItem(context, col1) + .withTitle("Author2") + .withIssueDate("2016-02-13") + .withAuthor("Smith, Maria") + .withRelationshipType("Person") + .build(); + + //2. One workspace item. + WorkspaceItem workspaceItem = WorkspaceItemBuilder.createWorkspaceItem(context, col1) + .withRelationshipType("Publication") + .build(); + + EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + EntityType person = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); + + + RelationshipType isAuthorOfPublication = RelationshipTypeBuilder.createRelationshipTypeBuilder(context, publication, person, "isAuthorOfPublication", + "isPublicationOfAuthor", 2, null, 0, + null).withCopyToLeft(false).withCopyToRight(true).build(); + + Relationship relationship1 = RelationshipBuilder.createRelationshipBuilder(context, workspaceItem.getItem(), author1, isAuthorOfPublication).build(); + Relationship relationship2 = RelationshipBuilder.createRelationshipBuilder(context, workspaceItem.getItem(), author2, isAuthorOfPublication).build(); + + context.restoreAuthSystemState(); + + String token = getAuthToken(admin.getEmail(), password); + + getClient(token).perform(delete("/api/core/relationships/" + relationship1.getID())) + .andExpect(status().is(400)); + + //Delete the workspaceitem + getClient(token).perform(delete("/api/submission/workspaceitems/" + workspaceItem.getID())) + .andExpect(status().is(204)); + + } + } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/builder/WorkspaceItemBuilder.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/builder/WorkspaceItemBuilder.java index 0c328a79e9..3ba2b4c0fb 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/builder/WorkspaceItemBuilder.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/builder/WorkspaceItemBuilder.java @@ -166,6 +166,10 @@ public class WorkspaceItemBuilder extends AbstractBuilder Date: Fri, 26 Jun 2020 10:54:34 +0200 Subject: [PATCH 002/179] [Task 71502] added forceDelete method to the RelationshipService that won't check the cardinality of the relationships. Used this in the ItemService delete and added tests --- .../org/dspace/content/ItemServiceImpl.java | 2 +- .../content/RelationshipServiceImpl.java | 40 ++++++++--- .../content/service/RelationshipService.java | 13 ++++ .../dspace/app/rest/ItemRestRepositoryIT.java | 66 +++++++++++-------- 4 files changed, 82 insertions(+), 39 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java index 9502a2ca32..c765f663f8 100644 --- a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java @@ -679,7 +679,7 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl implements It // Remove relationships for (Relationship relationship : relationshipService.findByItem(context, item)) { - relationshipService.delete(context, relationship, false, false); + relationshipService.forceDelete(context, relationship, false, false); } // Remove bundles diff --git a/dspace-api/src/main/java/org/dspace/content/RelationshipServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/RelationshipServiceImpl.java index 0f08b15635..d1ced67cd2 100644 --- a/dspace-api/src/main/java/org/dspace/content/RelationshipServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/RelationshipServiceImpl.java @@ -331,21 +331,43 @@ public class RelationshipServiceImpl implements RelationshipService { if (isRelationshipValidToDelete(context, relationship) && copyToItemPermissionCheck(context, relationship, copyToLeftItem, copyToRightItem)) { // To delete a relationship, a user must have WRITE permissions on one of the related Items - copyMetadataValues(context, relationship, copyToLeftItem, copyToRightItem); - if (authorizeService.authorizeActionBoolean(context, relationship.getLeftItem(), Constants.WRITE) || - authorizeService.authorizeActionBoolean(context, relationship.getRightItem(), Constants.WRITE)) { - relationshipDAO.delete(context, relationship); - updatePlaceInRelationship(context, relationship); - } else { - throw new AuthorizeException( - "You do not have write rights on this relationship's items"); - } + deleteRelationshipAndCopyToItem(context, relationship, copyToLeftItem, copyToRightItem); } else { throw new IllegalArgumentException("The relationship given was not valid"); } } + @Override + public void forceDelete(Context context, Relationship relationship, boolean copyToLeftItem, boolean copyToRightItem) + throws SQLException, AuthorizeException { + log.info(org.dspace.core.LogManager.getHeader(context, "delete_relationship", + "relationship_id=" + relationship.getID() + "&" + + "copyMetadataValuesToLeftItem=" + copyToLeftItem + "&" + + "copyMetadataValuesToRightItem=" + copyToRightItem)); + if (copyToItemPermissionCheck(context, relationship, copyToLeftItem, copyToRightItem)) { + // To delete a relationship, a user must have WRITE permissions on one of the related Items + deleteRelationshipAndCopyToItem(context, relationship, copyToLeftItem, copyToRightItem); + + } else { + throw new IllegalArgumentException("The relationship given was not valid"); + } + } + + private void deleteRelationshipAndCopyToItem(Context context, Relationship relationship, boolean copyToLeftItem, + boolean copyToRightItem) throws SQLException, AuthorizeException { + copyMetadataValues(context, relationship, copyToLeftItem, copyToRightItem); + if (authorizeService.authorizeActionBoolean(context, relationship.getLeftItem(), Constants.WRITE) || + authorizeService.authorizeActionBoolean(context, relationship.getRightItem(), Constants.WRITE)) { + relationshipDAO.delete(context, relationship); + updatePlaceInRelationship(context, relationship); + } else { + throw new AuthorizeException( + "You do not have write rights on this relationship's items"); + } + } + + /** * Converts virtual metadata from RelationshipMetadataValue objects to actual item metadata. * diff --git a/dspace-api/src/main/java/org/dspace/content/service/RelationshipService.java b/dspace-api/src/main/java/org/dspace/content/service/RelationshipService.java index 97f4924a59..185d00a7b0 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/RelationshipService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/RelationshipService.java @@ -315,4 +315,17 @@ public interface RelationshipService extends DSpaceCRUDService { */ void delete(Context context, Relationship relationship, boolean copyToLeftItem, boolean copyToRightItem) throws SQLException, AuthorizeException; + /** + * This method is used to delete a Relationship whilst given the possibility to copy the Virtual Metadata created + * by this relationship to the left and/or right item. + * This method will bypass the cardinality checks on the {@link RelationshipType} for the given {@link Relationship} + * This should only be used during the deletion of items so that the min cardinality check can't disallow items + * to be deleted + * @param context The relevant DSpace context + * @param relationship The relationship to be deleted + * @param copyToLeftItem A boolean indicating whether we should copy metadata to the left item or not + * @param copyToRightItem A boolean indicating whether we should copy metadata to the right item or not + */ + void forceDelete(Context context, Relationship relationship, boolean copyToLeftItem, boolean copyToRightItem) + throws SQLException, AuthorizeException; } \ No newline at end of file diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java index ddfd63e446..4dd4112cb9 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java @@ -2717,38 +2717,41 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { .createCollection(context, parentCommunity).withName("Collection 1").build(); Item author1 = ItemBuilder.createItem(context, col1) - .withTitle("Author1") - .withIssueDate("2017-10-17") - .withAuthor("Smith, Donald") - .withPersonIdentifierLastName("Smith") - .withPersonIdentifierFirstName("Donald") - .withRelationshipType("Person") - .build(); + .withTitle("Author1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withPersonIdentifierLastName("Smith") + .withPersonIdentifierFirstName("Donald") + .withRelationshipType("Person") + .build(); Item author2 = ItemBuilder.createItem(context, col1) - .withTitle("Author2") - .withIssueDate("2016-02-13") - .withAuthor("Smith, Maria") - .withRelationshipType("Person") - .build(); + .withTitle("Author2") + .withIssueDate("2016-02-13") + .withAuthor("Smith, Maria") + .withRelationshipType("Person") + .build(); Item publication1 = ItemBuilder.createItem(context, col1) - .withTitle("Publication1") - .withAuthor("Testy, TEst") - .withIssueDate("2015-01-01") - .withRelationshipType("Publication") - .build(); + .withTitle("Publication1") + .withAuthor("Testy, TEst") + .withIssueDate("2015-01-01") + .withRelationshipType("Publication") + .build(); EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); EntityType person = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); - RelationshipType isAuthorOfPublication = RelationshipTypeBuilder.createRelationshipTypeBuilder(context, publication, person, "isAuthorOfPublication", - "isPublicationOfAuthor", 2, null, 0, - null).withCopyToLeft(false).withCopyToRight(true).build(); + RelationshipType isAuthorOfPublication = RelationshipTypeBuilder + .createRelationshipTypeBuilder(context, publication, person, "isAuthorOfPublication", + "isPublicationOfAuthor", 2, null, 0, + null).withCopyToLeft(false).withCopyToRight(true).build(); - Relationship relationship1 = RelationshipBuilder.createRelationshipBuilder(context, publication1, author1, isAuthorOfPublication).build(); - Relationship relationship2 = RelationshipBuilder.createRelationshipBuilder(context, publication1, author2, isAuthorOfPublication).build(); + Relationship relationship1 = RelationshipBuilder + .createRelationshipBuilder(context, publication1, author1, isAuthorOfPublication).build(); + Relationship relationship2 = RelationshipBuilder + .createRelationshipBuilder(context, publication1, author2, isAuthorOfPublication).build(); context.restoreAuthSystemState(); @@ -2759,8 +2762,8 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { //Delete public item getClient(token).perform(delete("/api/core/items/" + publication1.getID())) .andExpect(status().is(204)); - - + getClient(token).perform(get("/api/core/items/" + publication1.getID())) + .andExpect(status().is(404)); } @@ -2801,12 +2804,15 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { EntityType person = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); - RelationshipType isAuthorOfPublication = RelationshipTypeBuilder.createRelationshipTypeBuilder(context, publication, person, "isAuthorOfPublication", - "isPublicationOfAuthor", 2, null, 0, - null).withCopyToLeft(false).withCopyToRight(true).build(); + RelationshipType isAuthorOfPublication = RelationshipTypeBuilder + .createRelationshipTypeBuilder(context, publication, person, "isAuthorOfPublication", + "isPublicationOfAuthor", 2, null, 0, + null).withCopyToLeft(false).withCopyToRight(true).build(); - Relationship relationship1 = RelationshipBuilder.createRelationshipBuilder(context, workspaceItem.getItem(), author1, isAuthorOfPublication).build(); - Relationship relationship2 = RelationshipBuilder.createRelationshipBuilder(context, workspaceItem.getItem(), author2, isAuthorOfPublication).build(); + Relationship relationship1 = RelationshipBuilder + .createRelationshipBuilder(context, workspaceItem.getItem(), author1, isAuthorOfPublication).build(); + Relationship relationship2 = RelationshipBuilder + .createRelationshipBuilder(context, workspaceItem.getItem(), author2, isAuthorOfPublication).build(); context.restoreAuthSystemState(); @@ -2818,6 +2824,8 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { //Delete the workspaceitem getClient(token).perform(delete("/api/submission/workspaceitems/" + workspaceItem.getID())) .andExpect(status().is(204)); + getClient(token).perform(get("/api/submission/workspaceitems/" + workspaceItem.getID())) + .andExpect(status().is(404)); } From 0f433ed2ae5a6f8a1a2de038df502a4890e2b316 Mon Sep 17 00:00:00 2001 From: Raf Ponsaerts Date: Fri, 26 Jun 2020 11:17:40 +0200 Subject: [PATCH 003/179] [Task 71502] moved workspaceItemTest to the workspaceItemRestRepository --- .../dspace/app/rest/ItemRestRepositoryIT.java | 62 ----------------- .../rest/WorkspaceItemRestRepositoryIT.java | 68 +++++++++++++++++++ 2 files changed, 68 insertions(+), 62 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java index 4dd4112cb9..b510ffeb28 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java @@ -2767,67 +2767,5 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { } - @Test - public void deleteWorkspaceItemWithMinRelationshipsTest() throws Exception { - context.turnOffAuthorisationSystem(); - - //** GIVEN ** - //1. A community with one collection. - parentCommunity = CommunityBuilder.createCommunity(context) - .withName("Parent Community") - .build(); - Collection col1 = CollectionBuilder - .createCollection(context, parentCommunity).withName("Collection 1").build(); - - Item author1 = ItemBuilder.createItem(context, col1) - .withTitle("Author1") - .withIssueDate("2017-10-17") - .withAuthor("Smith, Donald") - .withPersonIdentifierLastName("Smith") - .withPersonIdentifierFirstName("Donald") - .withRelationshipType("Person") - .build(); - - Item author2 = ItemBuilder.createItem(context, col1) - .withTitle("Author2") - .withIssueDate("2016-02-13") - .withAuthor("Smith, Maria") - .withRelationshipType("Person") - .build(); - - //2. One workspace item. - WorkspaceItem workspaceItem = WorkspaceItemBuilder.createWorkspaceItem(context, col1) - .withRelationshipType("Publication") - .build(); - - EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); - EntityType person = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); - - - RelationshipType isAuthorOfPublication = RelationshipTypeBuilder - .createRelationshipTypeBuilder(context, publication, person, "isAuthorOfPublication", - "isPublicationOfAuthor", 2, null, 0, - null).withCopyToLeft(false).withCopyToRight(true).build(); - - Relationship relationship1 = RelationshipBuilder - .createRelationshipBuilder(context, workspaceItem.getItem(), author1, isAuthorOfPublication).build(); - Relationship relationship2 = RelationshipBuilder - .createRelationshipBuilder(context, workspaceItem.getItem(), author2, isAuthorOfPublication).build(); - - context.restoreAuthSystemState(); - - String token = getAuthToken(admin.getEmail(), password); - - getClient(token).perform(delete("/api/core/relationships/" + relationship1.getID())) - .andExpect(status().is(400)); - - //Delete the workspaceitem - getClient(token).perform(delete("/api/submission/workspaceitems/" + workspaceItem.getID())) - .andExpect(status().is(204)); - getClient(token).perform(get("/api/submission/workspaceitems/" + workspaceItem.getID())) - .andExpect(status().is(404)); - - } - } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java index c4a64c6de1..40820c8cd6 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java @@ -39,8 +39,11 @@ import org.dspace.app.rest.builder.BitstreamBuilder; import org.dspace.app.rest.builder.CollectionBuilder; import org.dspace.app.rest.builder.CommunityBuilder; import org.dspace.app.rest.builder.EPersonBuilder; +import org.dspace.app.rest.builder.EntityTypeBuilder; import org.dspace.app.rest.builder.GroupBuilder; import org.dspace.app.rest.builder.ItemBuilder; +import org.dspace.app.rest.builder.RelationshipBuilder; +import org.dspace.app.rest.builder.RelationshipTypeBuilder; import org.dspace.app.rest.builder.WorkspaceItemBuilder; import org.dspace.app.rest.matcher.CollectionMatcher; import org.dspace.app.rest.matcher.ItemMatcher; @@ -54,7 +57,10 @@ import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.content.Bitstream; import org.dspace.content.Collection; import org.dspace.content.Community; +import org.dspace.content.EntityType; import org.dspace.content.Item; +import org.dspace.content.Relationship; +import org.dspace.content.RelationshipType; import org.dspace.content.WorkspaceItem; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; @@ -3803,4 +3809,66 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration Matchers.is(WorkspaceItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem, "Test title", "2019-04-25", "ExtraEntry")))); } + + @Test + public void deleteWorkspaceItemWithMinRelationshipsTest() throws Exception { + context.turnOffAuthorisationSystem(); + + //** GIVEN ** + //1. A community with one collection. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection col1 = CollectionBuilder + .createCollection(context, parentCommunity).withName("Collection 1").build(); + + Item author1 = ItemBuilder.createItem(context, col1) + .withTitle("Author1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withPersonIdentifierLastName("Smith") + .withPersonIdentifierFirstName("Donald") + .withRelationshipType("Person") + .build(); + + Item author2 = ItemBuilder.createItem(context, col1) + .withTitle("Author2") + .withIssueDate("2016-02-13") + .withAuthor("Smith, Maria") + .withRelationshipType("Person") + .build(); + + //2. One workspace item. + WorkspaceItem workspaceItem = WorkspaceItemBuilder.createWorkspaceItem(context, col1) + .withRelationshipType("Publication") + .build(); + + EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + EntityType person = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); + + + RelationshipType isAuthorOfPublication = RelationshipTypeBuilder + .createRelationshipTypeBuilder(context, publication, person, "isAuthorOfPublication", + "isPublicationOfAuthor", 2, null, 0, + null).withCopyToLeft(false).withCopyToRight(true).build(); + + Relationship relationship1 = RelationshipBuilder + .createRelationshipBuilder(context, workspaceItem.getItem(), author1, isAuthorOfPublication).build(); + Relationship relationship2 = RelationshipBuilder + .createRelationshipBuilder(context, workspaceItem.getItem(), author2, isAuthorOfPublication).build(); + + context.restoreAuthSystemState(); + + String token = getAuthToken(admin.getEmail(), password); + + getClient(token).perform(delete("/api/core/relationships/" + relationship1.getID())) + .andExpect(status().is(400)); + + //Delete the workspaceitem + getClient(token).perform(delete("/api/submission/workspaceitems/" + workspaceItem.getID())) + .andExpect(status().is(204)); + getClient(token).perform(get("/api/submission/workspaceitems/" + workspaceItem.getID())) + .andExpect(status().is(404)); + + } } From 9a8f81db44b9e3005c5f3d2439dab56917271097 Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Wed, 14 Oct 2020 13:51:46 +0200 Subject: [PATCH 004/179] Merge conflicts --- .../test/java/org/dspace/app/rest/ItemRestRepositoryIT.java | 3 +++ .../org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java index 3e8889796d..c801be28d6 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java @@ -49,8 +49,11 @@ import org.dspace.builder.BitstreamBuilder; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.EPersonBuilder; +import org.dspace.builder.EntityTypeBuilder; import org.dspace.builder.GroupBuilder; import org.dspace.builder.ItemBuilder; +import org.dspace.builder.RelationshipBuilder; +import org.dspace.builder.RelationshipTypeBuilder; import org.dspace.builder.ResourcePolicyBuilder; import org.dspace.builder.WorkspaceItemBuilder; import org.dspace.content.Bitstream; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java index 2bd4636e32..f43aca718a 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java @@ -49,8 +49,11 @@ import org.dspace.builder.BitstreamBuilder; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.EPersonBuilder; +import org.dspace.builder.EntityTypeBuilder; import org.dspace.builder.GroupBuilder; import org.dspace.builder.ItemBuilder; +import org.dspace.builder.RelationshipBuilder; +import org.dspace.builder.RelationshipTypeBuilder; import org.dspace.builder.WorkspaceItemBuilder; import org.dspace.content.Bitstream; import org.dspace.content.Collection; From ff436491fb1df139112b27874987660efb434f18 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Fri, 13 Nov 2020 10:40:43 +0100 Subject: [PATCH 005/179] implemented new methods as createAndReturn for claimedTask and search methods for ClaimedTask and PoolTask --- .../repository/ClaimedTaskRestRepository.java | 93 ++++++++++++++++ .../repository/PoolTaskRestRepository.java | 101 ++++++++++++------ ...rnalSourceEntryPoolTaskUriListHandler.java | 75 +++++++++++++ 3 files changed, 234 insertions(+), 35 deletions(-) create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/handler/ExternalSourceEntryPoolTaskUriListHandler.java diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java index f5b60eedfc..386ca5dc55 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java @@ -25,9 +25,11 @@ import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.ClaimedTaskRest; import org.dspace.app.rest.model.PoolTaskRest; +import org.dspace.app.rest.repository.handler.service.UriListHandlerService; import org.dspace.app.util.Util; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.service.AuthorizeService; +import org.dspace.content.Item; import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.dspace.eperson.EPerson; @@ -42,8 +44,10 @@ import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.state.actions.Action; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; +import org.dspace.xmlworkflow.storedcomponents.PoolTask; import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; @@ -86,6 +90,12 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository findAllByItem(@Parameter(value = "uuid", required = true) UUID itemUUID, + Pageable pageable) { + List tasks = null; + try { + Context context = obtainContext(); + EPerson currentUser = context.getCurrentUser(); + if (currentUser == null) { + throw new RESTAuthorizationException( + "This endpoint is available only to logged-in user to search for their" + + " own claimed tasks or the admins"); + } + Item item = itemService.find(context, itemUUID); + if (item == null) { + return null; + } + XmlWorkflowItem xmlWFI = xmlWorkflowItemService.findByItem(context, item); + if (xmlWFI == null) { + return null; + } else { + tasks = claimedTaskService.findByWorkflowItem(context, xmlWFI); + } + return converter.toRestPage(tasks, pageable, utils.obtainProjection()); + } catch (SQLException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + @SearchRestMethod(name = "findByItem") + public ClaimedTaskRest findByItem(@Parameter(value = "uuid", required = true) UUID itemUUID) { + ClaimedTask claimedTask = null; + try { + Context context = obtainContext(); + EPerson currentUser = context.getCurrentUser(); + if (currentUser == null) { + throw new RESTAuthorizationException( + "This endpoint is available only to logged-in user to search for their" + + " own claimed tasks or the admins"); + } + Item item = itemService.find(context, itemUUID); + if (item == null) { + return null; + } + XmlWorkflowItem xmlWFI = xmlWorkflowItemService.findByItem(context, item); + if (xmlWFI == null) { + return null; + } else { + claimedTask = claimedTaskService.findByWorkflowIdAndEPerson(context, xmlWFI, currentUser); + } + return converter.toRest(claimedTask, utils.obtainProjection()); + } catch (SQLException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + @Override public Class getDomainClass() { return ClaimedTaskRest.class; @@ -197,6 +263,33 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository list) + throws AuthorizeException, SQLException, RepositoryMethodNotImplementedException { + HttpServletRequest request = getRequestService().getCurrentRequest().getHttpServletRequest(); + ClaimedTask claimedTask = null; + try { + PoolTask task = uriListHandlerService.handle(context, request, list, PoolTask.class); + if (task == null) { + throw + new IllegalArgumentException("No PoolTask record found, the uri-list does not contait a resource"); + } + XmlWorkflowServiceFactory factory = (XmlWorkflowServiceFactory) XmlWorkflowServiceFactory.getInstance(); + Workflow workflow = factory.getWorkflowFactory().getWorkflow(task.getWorkflowItem().getCollection()); + Step step = workflow.getStep(task.getStepID()); + WorkflowActionConfig currentActionConfig = step.getActionConfig(task.getActionID()); + workflowService.doState(context, context.getCurrentUser(), request, task.getWorkflowItem().getID(), + workflow, currentActionConfig); + claimedTask = claimedTaskService.findByWorkflowIdAndEPerson(context, + task.getWorkflowItem(), context.getCurrentUser()); + } catch (AuthorizeException e) { + throw new RESTAuthorizationException(e); + } catch (WorkflowConfigurationException | MessagingException | WorkflowException | IOException e) { + throw new UnprocessableEntityException(e.getMessage(), e); + } + return converter.toRest(claimedTask, utils.obtainProjection()); + } + @Override public void afterPropertiesSet() throws Exception { discoverableEndpointsService.register(this, Arrays.asList( diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/PoolTaskRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/PoolTaskRestRepository.java index 9faa86a09c..475a36ba31 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/PoolTaskRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/PoolTaskRestRepository.java @@ -12,37 +12,30 @@ import java.sql.SQLException; import java.util.Arrays; import java.util.List; import java.util.UUID; -import javax.mail.MessagingException; -import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; import org.dspace.app.rest.DiscoverableEndpointsService; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; import org.dspace.app.rest.exception.RESTAuthorizationException; -import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.PoolTaskRest; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.service.AuthorizeService; +import org.dspace.content.Item; import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.service.EPersonService; -import org.dspace.workflow.WorkflowException; -import org.dspace.xmlworkflow.WorkflowConfigurationException; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; import org.dspace.xmlworkflow.service.XmlWorkflowService; -import org.dspace.xmlworkflow.state.Step; -import org.dspace.xmlworkflow.state.Workflow; -import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.dspace.xmlworkflow.storedcomponents.PoolTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.hateoas.Link; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; @@ -80,6 +73,9 @@ public class PoolTaskRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { throw new RuntimeException("Method not allowed!"); @@ -161,4 +132,64 @@ public class PoolTaskRestRepository extends DSpaceRestRepository findAllByItem(@Parameter(value = "uuid", required = true) UUID itemUUID, + Pageable pageable) { + List poolTasks = null; + try { + Context context = obtainContext(); + EPerson currentUser = context.getCurrentUser(); + if (currentUser == null) { + throw new RESTAuthorizationException( + "This endpoint is available only to logged-in user to search for their" + + " own claimed tasks or the admins"); + } + Item item = itemService.find(context, itemUUID); + if (item == null) { + return null; + } + XmlWorkflowItem xmlWorkflowItem = xmlWorkflowItemService.findByItem(context, item); + if (xmlWorkflowItem == null) { + return null; + } else { + poolTasks = poolTaskService.find(context, xmlWorkflowItem); + } + return converter.toRestPage(poolTasks, pageable, utils.obtainProjection()); + } catch (SQLException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + @SearchRestMethod(name = "findByItem") + public PoolTaskRest findByItem(@Parameter(value = "uuid", required = true) UUID itemUUID) { + PoolTask poolTask = null; + try { + Context context = obtainContext(); + EPerson currentUser = context.getCurrentUser(); + if (currentUser == null) { + throw new RESTAuthorizationException( + "This endpoint is available only to logged-in user to search for their" + + " own claimed tasks or the admins"); + } + if (authorizeService.isAdmin(context)) { + Item item = itemService.find(context, itemUUID); + if (item == null) { + return null; + } + XmlWorkflowItem xmlWorkflowItem = xmlWorkflowItemService.findByItem(context, item); + if (xmlWorkflowItem == null) { + return null; + } else { + poolTask = poolTaskService.findByWorkflowIdAndEPerson(context, xmlWorkflowItem, currentUser); + } + } else { + throw new RESTAuthorizationException("Only administrators can search for pool tasks of other users"); + } + return converter.toRest(poolTask, utils.obtainProjection()); + } catch (SQLException | AuthorizeException | IOException e) { + throw new RuntimeException(e.getMessage(), e); + } + } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/handler/ExternalSourceEntryPoolTaskUriListHandler.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/handler/ExternalSourceEntryPoolTaskUriListHandler.java new file mode 100644 index 0000000000..7d2fc08386 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/handler/ExternalSourceEntryPoolTaskUriListHandler.java @@ -0,0 +1,75 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.rest.repository.handler; + +import java.sql.SQLException; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.servlet.http.HttpServletRequest; + +import org.dspace.authorize.AuthorizeException; +import org.dspace.core.Context; +import org.dspace.xmlworkflow.storedcomponents.PoolTask; +import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * This class extends the {@link ExternalSourceEntryItemUriListHandler} abstract class and implements it specifically + * for the List objects. + * + * @author Mykhaylo Boychuk (mykhaylo.boychuk at 4science.it) + */ +@Component +public class ExternalSourceEntryPoolTaskUriListHandler extends ExternalSourceEntryItemUriListHandler { + + @Autowired + private PoolTaskService poolTaskService; + + @Override + public boolean supports(List uriList, String method, Class clazz) { + if (clazz != PoolTask.class) { + return false; + } + return true; + } + + @Override + public PoolTask handle(Context context, HttpServletRequest request, List uriList) + throws SQLException, AuthorizeException { + return getObjectFromUriList(context, uriList); + } + + @Override + public boolean validate(Context context, HttpServletRequest request, List uriList) + throws AuthorizeException { + if (uriList.size() > 1) { + return false; + } + return true; + } + + + private PoolTask getObjectFromUriList(Context context, List uriList) { + PoolTask poolTask = null; + String url = uriList.get(0); + Pattern pattern = Pattern.compile("\\/api\\/workflow\\/pooltasks\\/(.*)"); + Matcher matcher = pattern.matcher(url); + + matcher.find(); + String id = matcher.group(1); + Integer poolTaskId = Integer.parseInt(id); + try { + poolTask = poolTaskService.find(context, poolTaskId); + } catch (SQLException e) { + throw new RuntimeException(e.getMessage(), e); + } + return poolTask; + } +} \ No newline at end of file From 86a6819dd802e00aa0e83d374f38d88eb1431734 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Fri, 13 Nov 2020 12:43:52 +0100 Subject: [PATCH 006/179] fixed tests --- .../repository/ClaimedTaskRestRepository.java | 2 +- .../app/rest/TaskRestRepositoriesIT.java | 160 +++++++++++++----- 2 files changed, 116 insertions(+), 46 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java index 386ca5dc55..1361b0efd6 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java @@ -272,7 +272,7 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository idRef = new AtomicReference(); + AtomicReference idRefClaimedTask = new AtomicReference(); Step step = xmlWorkflowFactory.getStepByName("reviewstep"); // step 1 @@ -1837,9 +1845,12 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .set(read(result.getResponse().getContentAsString(), "$._embedded.pooltasks[0].id")))); // claim the task - getClient(reviewer1Token).perform(post("/api/workflow/pooltasks/" + idRef.get()) - .contentType(MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().isNoContent()); + getClient(reviewer1Token).perform(post("/api/workflow/claimedtasks") + .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) + .content("/api/workflow/pooltasks/" + idRef.get())) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) + .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); WorkflowActionConfig workflowAction = xmlWorkflowFactory.getActionByName("reviewaction"); @@ -1864,6 +1875,8 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andDo((result -> idRef .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); + assertEquals(idRefClaimedTask.get(), idRef.get()); + // approve the claimedTask, wf step 1 getClient(reviewer1Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) .param("submit_approve", "true") @@ -1896,9 +1909,12 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .set(read(result.getResponse().getContentAsString(), "$._embedded.pooltasks[0].id")))); // claim the task - getClient(reviewer2Token).perform(post("/api/workflow/pooltasks/" + idRef.get()) - .contentType(MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().isNoContent()); + getClient(reviewer2Token).perform(post("/api/workflow/claimedtasks") + .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) + .content("/api/workflow/pooltasks/" + idRef.get())) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) + .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); workflowAction = xmlWorkflowFactory.getActionByName("editaction"); @@ -1923,6 +1939,8 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andDo((result -> idRef .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); + assertEquals(idRefClaimedTask.get(), idRef.get()); + // approve the claimedTask, wf step 2 getClient(reviewer2Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) .param("submit_approve", "true") @@ -1955,9 +1973,12 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .set(read(result.getResponse().getContentAsString(), "$._embedded.pooltasks[0].id")))); // claim the task - getClient(reviewer3Token).perform(post("/api/workflow/pooltasks/" + idRef.get()) - .contentType(MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().isNoContent()); + getClient(reviewer3Token).perform(post("/api/workflow/claimedtasks") + .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) + .content("/api/workflow/pooltasks/" + idRef.get())) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) + .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); workflowAction = xmlWorkflowFactory.getActionByName("finaleditaction"); // get the id of the claimed task @@ -1981,6 +2002,8 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andDo((result -> idRef .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); + assertEquals(idRefClaimedTask.get(), idRef.get()); + // approve the claimedTask, wf step 3 getClient(reviewer3Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) .param("submit_approve", "true") @@ -2043,6 +2066,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String adminToken = getAuthToken(admin.getEmail(), password); AtomicReference idRef = new AtomicReference(); + AtomicReference idRefClaimedTask = new AtomicReference(); // step 1 getClient(reviewer1Token).perform(get("/api/workflow/pooltasks/search/findByUser") @@ -2062,9 +2086,12 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .set(read(result.getResponse().getContentAsString(), "$._embedded.pooltasks[0].id")))); // claim the task - getClient(reviewer1Token).perform(post("/api/workflow/pooltasks/" + idRef.get()) - .contentType(MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().isNoContent()); + getClient(reviewer1Token).perform(post("/api/workflow/claimedtasks") + .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) + .content("/api/workflow/pooltasks/" + idRef.get())) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) + .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); // get the id of the claimed task getClient(reviewer1Token).perform(get("/api/workflow/claimedtasks/search/findByUser") @@ -2084,6 +2111,8 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andDo((result -> idRef .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); + assertEquals(idRefClaimedTask.get(), idRef.get()); + // reject the claimedTask with reason, default wf step 1 - review step getClient(reviewer1Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) .param("submit_reject", "true") @@ -2155,6 +2184,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String reviewer1Token = getAuthToken(reviewer1.getEmail(), password); AtomicReference idRef = new AtomicReference(); + AtomicReference idRefClaimedTask = new AtomicReference(); // step 1 getClient(reviewer1Token).perform(get("/api/workflow/pooltasks/search/findByUser") @@ -2174,9 +2204,12 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .set(read(result.getResponse().getContentAsString(), "$._embedded.pooltasks[0].id")))); // claim the task - getClient(reviewer1Token).perform(post("/api/workflow/pooltasks/" + idRef.get()) - .contentType(MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().isNoContent()); + getClient(reviewer1Token).perform(post("/api/workflow/claimedtasks") + .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) + .content("/api/workflow/pooltasks/" + idRef.get())) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) + .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); // get the id of the claimed task getClient(reviewer1Token).perform(get("/api/workflow/claimedtasks/search/findByUser") @@ -2196,6 +2229,8 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andDo((result -> idRef .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); + assertEquals(idRefClaimedTask.get(), idRef.get()); + // try non valid option (submit_edit_metadata), in default wf step 1 (review step) getClient(reviewer1Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) .param("submit_edit_metadata", "true") @@ -2257,6 +2292,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String adminToken = getAuthToken(admin.getEmail(), password); AtomicReference idRef = new AtomicReference(); + AtomicReference idRefClaimedTask = new AtomicReference(); // step 2 getClient(reviewer2Token).perform(get("/api/workflow/pooltasks/search/findByUser") @@ -2276,9 +2312,12 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .set(read(result.getResponse().getContentAsString(), "$._embedded.pooltasks[0].id")))); // claim the task - getClient(reviewer2Token).perform(post("/api/workflow/pooltasks/" + idRef.get()) - .contentType(MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().isNoContent()); + getClient(reviewer2Token).perform(post("/api/workflow/claimedtasks") + .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) + .content("/api/workflow/pooltasks/" + idRef.get())) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) + .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); // get the id of the claimed task getClient(reviewer2Token).perform(get("/api/workflow/claimedtasks/search/findByUser") @@ -2298,6 +2337,8 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andDo((result -> idRef .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); + assertEquals(idRefClaimedTask.get(), idRef.get()); + // reject the claimedTask, default wf step 2 (edit step) getClient(reviewer2Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) .param("submit_reject", "true") @@ -2370,6 +2411,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String adminToken = getAuthToken(admin.getEmail(), password); AtomicReference idRef = new AtomicReference(); + AtomicReference idRefClaimedTask = new AtomicReference(); // step 2 getClient(reviewer2Token).perform(get("/api/workflow/pooltasks/search/findByUser") @@ -2389,9 +2431,15 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .set(read(result.getResponse().getContentAsString(), "$._embedded.pooltasks[0].id")))); // claim the task - getClient(reviewer2Token).perform(post("/api/workflow/pooltasks/" + idRef.get()) - .contentType(MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().isNoContent()); +// getClient(reviewer2Token).perform(post("/api/workflow/pooltasks/" + idRef.get()) +// .contentType(MediaType.APPLICATION_FORM_URLENCODED)) +// .andExpect(status().isNoContent()); + getClient(reviewer2Token).perform(post("/api/workflow/claimedtasks") + .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) + .content("/api/workflow/pooltasks/" + idRef.get())) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) + .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); // get the id of the claimed task getClient(reviewer2Token).perform(get("/api/workflow/claimedtasks/search/findByUser") @@ -2411,6 +2459,8 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andDo((result -> idRef .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); + assertEquals(idRefClaimedTask.get(), idRef.get()); + // try non valid option (submit_edit_metadata), default wf step 2 (edit step) getClient(reviewer2Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) .param("submit_non_valid_option", "true") @@ -2478,6 +2528,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String adminToken = getAuthToken(admin.getEmail(), password); AtomicReference idRef = new AtomicReference(); + AtomicReference idRefClaimedTask = new AtomicReference(); // step 3 getClient(reviewer3Token).perform(get("/api/workflow/pooltasks/search/findByUser") @@ -2497,9 +2548,12 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .set(read(result.getResponse().getContentAsString(), "$._embedded.pooltasks[0].id")))); // claim the task - getClient(reviewer3Token).perform(post("/api/workflow/pooltasks/" + idRef.get()) - .contentType(MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().isNoContent()); + getClient(reviewer3Token).perform(post("/api/workflow/claimedtasks") + .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) + .content("/api/workflow/pooltasks/" + idRef.get())) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) + .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); // get the id of the claimed task getClient(reviewer3Token).perform(get("/api/workflow/claimedtasks/search/findByUser") @@ -2519,6 +2573,8 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andDo((result -> idRef .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); + assertEquals(idRefClaimedTask.get(), idRef.get()); + // reject the claimedTask, default wf step 3 (final edit step) getClient(reviewer3Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) .param("submit_reject", "true") @@ -2586,6 +2642,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String adminToken = getAuthToken(admin.getEmail(), password); AtomicReference idRef = new AtomicReference(); + AtomicReference idRefClaimedTask = new AtomicReference(); // step 3 getClient(reviewer3Token).perform(get("/api/workflow/pooltasks/search/findByUser") @@ -2605,9 +2662,12 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .set(read(result.getResponse().getContentAsString(), "$._embedded.pooltasks[0].id")))); // claim the task - getClient(reviewer3Token).perform(post("/api/workflow/pooltasks/" + idRef.get()) - .contentType(MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().isNoContent()); + getClient(reviewer3Token).perform(post("/api/workflow/claimedtasks") + .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) + .content("/api/workflow/pooltasks/" + idRef.get())) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) + .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); // get the id of the claimed task getClient(reviewer3Token).perform(get("/api/workflow/claimedtasks/search/findByUser") @@ -2627,6 +2687,8 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andDo((result -> idRef .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); + assertEquals(idRefClaimedTask.get(), idRef.get()); + // edit metadata of the claimedTask, default wf step 3 (final edit step) getClient(reviewer3Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) .param("submit_edit_metadata", "true") @@ -2684,6 +2746,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String adminToken = getAuthToken(admin.getEmail(), password); AtomicReference idRef = new AtomicReference(); + AtomicReference idRefClaimedTask = new AtomicReference(); // step 3 getClient(reviewer3Token).perform(get("/api/workflow/pooltasks/search/findByUser") @@ -2703,9 +2766,12 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .set(read(result.getResponse().getContentAsString(), "$._embedded.pooltasks[0].id")))); // claim the task - getClient(reviewer3Token).perform(post("/api/workflow/pooltasks/" + idRef.get()) - .contentType(MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().isNoContent()); + getClient(reviewer3Token).perform(post("/api/workflow/claimedtasks") + .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) + .content("/api/workflow/pooltasks/" + idRef.get())) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) + .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); // get the id of the claimed task getClient(reviewer3Token).perform(get("/api/workflow/claimedtasks/search/findByUser") @@ -2725,6 +2791,8 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andDo((result -> idRef .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); + assertEquals(idRefClaimedTask.get(), idRef.get()); + // non valid option in the default wf step 3 (final edit step) getClient(reviewer3Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) .param("submit_non_valid_option", "true") @@ -3012,9 +3080,11 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .set(read(result.getResponse().getContentAsString(), "$._embedded.pooltasks[0].id")))); // claim the task - getClient(reviewer1Token).perform(post("/api/workflow/pooltasks/" + idRef.get()) - .contentType(MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().isNoContent()); + getClient(reviewer1Token).perform(post("/api/workflow/claimedtasks") + .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) + .content("/api/workflow/pooltasks/" + idRef.get())) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))); // try to patch a workspace item while it is in a step that does not have the edit_metadata option (review step) String authToken = getAuthToken(eperson.getEmail(), password); From 170ea73144b16c2518235e13aad4a815646ad579 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Fri, 13 Nov 2020 14:32:01 +0100 Subject: [PATCH 007/179] fix failed test --- .../java/org/dspace/app/rest/LoginAsEPersonIT.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/LoginAsEPersonIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/LoginAsEPersonIT.java index 95412b514d..bf3b54c922 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/LoginAsEPersonIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/LoginAsEPersonIT.java @@ -46,6 +46,7 @@ import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.rest.webmvc.RestMediaTypes; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MvcResult; @@ -256,10 +257,12 @@ public class LoginAsEPersonIT extends AbstractControllerIntegrationTest { String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(post("/api/workflow/pooltasks/" + poolTask.getID()) - .header("X-On-Behalf-Of", reviewer.getID()) - .contentType(MediaType.APPLICATION_FORM_URLENCODED)) - .andExpect(status().isNoContent()); + getClient(authToken).perform(post("/api/workflow/claimedtasks") + .header("X-On-Behalf-Of", reviewer.getID()) + .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) + .content("/api/workflow/pooltasks/" + poolTask.getID())) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))); // verify that the pool task no longer exists getClient(authToken).perform(get("/api/workflow/pooltasks/" + poolTask.getID())) From f6e0712c49fcab44fc2715d495434583dad12606 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Mon, 16 Nov 2020 14:40:44 +0100 Subject: [PATCH 008/179] added ITs to prove the functionality of search methods --- .../app/rest/TaskRestRepositoriesIT.java | 808 ++++++++++++++++++ 1 file changed, 808 insertions(+) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java index ff506877a2..c9091e6913 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; import org.dspace.app.rest.matcher.ClaimedTaskMatcher; @@ -3162,4 +3163,811 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { bibtex.close(); } + @Test + public void findAllPooltasksByItemTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1, admin).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + PoolTask poolTask = PoolTaskBuilder.createPoolTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withSubject("ExtraEntry") + .build(); + + Item item1 = poolTask.getWorkflowItem().getItem(); + + PoolTask poolTask2 = PoolTaskBuilder.createPoolTask(context, col1, reviewer1) + .withTitle("Workflow Item 2") + .withIssueDate("2020-01-19") + .withAuthor("Tommaso, Donald").withAuthor("Shon, John") + .withSubject("ExtraEntry").build(); + + Item item2 = poolTask2.getWorkflowItem().getItem(); + + context.restoreAuthSystemState(); + + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/workflow/pooltasks/search/findAllByItem") + .param("uuid", item1.getID().toString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.pooltasks", Matchers.containsInAnyOrder( + Matchers.allOf( + Matchers.is(PoolTaskMatcher.matchPoolTask(null, "reviewstep")), hasJsonPath("$._embedded.workflowitem", + Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( + poolTask.getWorkflowItem(), "Workflow Item 1", "2017-10-17", "ExtraEntry"))) + )))) + .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/workflow/pooltasks"))) + .andExpect(jsonPath("$.page.totalElements", is(1))); + + getClient(tokenAdmin).perform(get("/api/workflow/pooltasks/search/findAllByItem") + .param("uuid", item2.getID().toString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.pooltasks", Matchers.containsInAnyOrder( + Matchers.allOf( + Matchers.is(PoolTaskMatcher.matchPoolTask(null, "reviewstep")), hasJsonPath("$._embedded.workflowitem", + Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( + poolTask2.getWorkflowItem(), "Workflow Item 2", "2020-01-19", "ExtraEntry"))) + )))) + .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/workflow/pooltasks"))) + .andExpect(jsonPath("$.page.totalElements", is(1))); + } + + @Test + public void findAllPooltasksByItemUnauthorizedTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1, admin).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + PoolTask poolTask = PoolTaskBuilder.createPoolTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + Item item1 = poolTask.getWorkflowItem().getItem(); + + context.restoreAuthSystemState(); + + getClient().perform(get("/api/workflow/pooltasks/search/findAllByItem") + .param("uuid", item1.getID().toString())) + .andExpect(status().isUnauthorized()); + } + + @Test + public void findAllPooltasksByItemForbiddenTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1, admin).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + PoolTask poolTask = PoolTaskBuilder.createPoolTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + Item item1 = poolTask.getWorkflowItem().getItem(); + + context.restoreAuthSystemState(); + + // Only Admin has access to this end point + + String tokenSubmitter = getAuthToken(submitter.getEmail(), password); + getClient(tokenSubmitter).perform(get("/api/workflow/pooltasks/search/findAllByItem") + .param("uuid", item1.getID().toString())) + .andExpect(status().isForbidden()); + + String tokenReviewer1 = getAuthToken(reviewer1.getEmail(), password); + getClient(tokenReviewer1).perform(get("/api/workflow/pooltasks/search/findAllByItem") + .param("uuid", item1.getID().toString())) + .andExpect(status().isForbidden()); + } + + @Test + public void findPooltaskByItemTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + EPerson reviewer2 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer2@example.com") + .withPassword(password).build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + + Collection col2 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 2") + .withWorkflowGroup(1, reviewer2).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + PoolTask poolTask = PoolTaskBuilder.createPoolTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + Item item1 = poolTask.getWorkflowItem().getItem(); + + PoolTask poolTask2 = PoolTaskBuilder.createPoolTask(context, col2, reviewer2) + .withTitle("Workflow Item 2") + .withIssueDate("2020-01-19") + .withAuthor("Tommaso, Donald").withAuthor("Shon, John") + .withSubject("ExtraEntry").build(); + + Item item2 = poolTask2.getWorkflowItem().getItem(); + + context.restoreAuthSystemState(); + + String tokenReviewer1 = getAuthToken(reviewer1.getEmail(), password); + getClient(tokenReviewer1).perform(get("/api/workflow/pooltasks/search/findByItem") + .param("uuid", item1.getID().toString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(poolTask.getID()))) + .andExpect(jsonPath("$.type", is("pooltask"))) + .andExpect(jsonPath("$", Matchers.is(PoolTaskMatcher.matchPoolTask(poolTask, "reviewstep")))) + .andExpect(jsonPath("$._embedded.workflowitem", + Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( + poolTask.getWorkflowItem(), "Workflow Item 1", "2017-10-17", "ExtraEntry")))); + + String tokenReviewer2 = getAuthToken(reviewer2.getEmail(), password); + getClient(tokenReviewer2).perform(get("/api/workflow/pooltasks/search/findByItem") + .param("uuid", item2.getID().toString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(poolTask2.getID()))) + .andExpect(jsonPath("$.type", is("pooltask"))) + .andExpect(jsonPath("$", Matchers.is(PoolTaskMatcher.matchPoolTask(poolTask2, "reviewstep")))) + .andExpect(jsonPath("$._embedded.workflowitem", + Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( + poolTask2.getWorkflowItem(), "Workflow Item 2", "2020-01-19", "ExtraEntry")))); + + } + + @Test + public void findPooltaskByItemNoContentTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + EPerson reviewer2 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer2@example.com") + .withPassword(password).build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + + Collection col2 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 2") + .withWorkflowGroup(1, reviewer2).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + PoolTask poolTask = PoolTaskBuilder.createPoolTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + Item item1 = poolTask.getWorkflowItem().getItem(); + + PoolTask poolTask2 = PoolTaskBuilder.createPoolTask(context, col2, reviewer2) + .withTitle("Workflow Item 2") + .withIssueDate("2020-01-19") + .withAuthor("Tommaso, Donald").withAuthor("Shon, John") + .withSubject("ExtraEntry").build(); + + Item item2 = poolTask2.getWorkflowItem().getItem(); + + context.restoreAuthSystemState(); + + String tokenSubmitter = getAuthToken(submitter.getEmail(), password); + getClient(tokenSubmitter).perform(get("/api/workflow/pooltasks/search/findByItem") + .param("uuid", item1.getID().toString())) + .andExpect(status().isNoContent()); + + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/workflow/pooltasks/search/findByItem") + .param("uuid", item1.getID().toString())) + .andExpect(status().isNoContent()); + + String tokenReviewer2 = getAuthToken(reviewer2.getEmail(), password); + getClient(tokenReviewer2).perform(get("/api/workflow/pooltasks/search/findByItem") + .param("uuid", item1.getID().toString())) + .andExpect(status().isNoContent()); + } + + @Test + public void findPooltaskByItemWrongUuidOfItemTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + PoolTask poolTask = PoolTaskBuilder.createPoolTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String tokenReviewer1 = getAuthToken(reviewer1.getEmail(), password); + getClient(tokenReviewer1).perform(get("/api/workflow/pooltasks/search/findByItem") + .param("uuid", UUID.randomUUID().toString())) + .andExpect(status().isNoContent()); + + } + + @Test + public void findPooltaskByItemUnauthorizedTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + EPerson reviewer2 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer2@example.com") + .withPassword(password).build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + + Collection col2 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 2") + .withWorkflowGroup(1, reviewer2).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + PoolTask poolTask = PoolTaskBuilder.createPoolTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + Item item1 = poolTask.getWorkflowItem().getItem(); + + context.restoreAuthSystemState(); + + getClient().perform(get("/api/workflow/pooltasks/search/findByItem") + .param("uuid", item1.getID().toString())) + .andExpect(status().isUnauthorized()); + + } + + @Test + public void findAllClaimedTaskByItemTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password) + .build(); + + EPerson reviewer2 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer2@example.com") + .withPassword(password) + .build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + Collection col2 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 2") + .withWorkflowGroup(1, reviewer2).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + ClaimedTask claimedTask1 = ClaimedTaskBuilder.createClaimedTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + ClaimedTask claimedTask2 = ClaimedTaskBuilder.createClaimedTask(context, col2, reviewer2) + .withTitle("Workflow Item 2") + .withIssueDate("2020-10-20") + .withAuthor("Tommaso, Donald").withAuthor("Shon, John") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String adminToken = getAuthToken(admin.getEmail(), password); + + getClient(adminToken).perform(get("/api/workflow/claimedtasks/search/findAllByItem") + .param("uuid", claimedTask1.getWorkflowItem().getItem().getID().toString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.claimedtasks", Matchers.containsInAnyOrder( + Matchers.allOf(hasJsonPath("$", ClaimedTaskMatcher.matchClaimedTask(claimedTask1, "reviewstep")), + hasJsonPath("$._embedded.workflowitem", + Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( + claimedTask1.getWorkflowItem(), "Workflow Item 1", "2017-10-17", "ExtraEntry"))))))) + .andExpect(jsonPath("$.page.totalElements", is(1))); + + getClient(adminToken).perform(get("/api/workflow/claimedtasks/search/findAllByItem") + .param("uuid", claimedTask2.getWorkflowItem().getItem().getID().toString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.claimedtasks", Matchers.containsInAnyOrder( + Matchers.allOf(hasJsonPath("$", ClaimedTaskMatcher.matchClaimedTask(claimedTask2, "reviewstep")), + hasJsonPath("$._embedded.workflowitem", + Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( + claimedTask2.getWorkflowItem(), "Workflow Item 2", "2020-10-20", "ExtraEntry"))))))) + .andExpect(jsonPath("$.page.totalElements", is(1))); + } + + @Test + public void findAllClaimedTaskByItemForbiddenTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + EPerson reviewer2 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer2@example.com") + .withPassword(password).build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community").build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community").build(); + Collection col1 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + Collection col2 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 2") + .withWorkflowGroup(1, reviewer2).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + ClaimedTask claimedTask1 = ClaimedTaskBuilder.createClaimedTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String tokenSubmitter = getAuthToken(submitter.getEmail(), password); + String tokenReviewer1 = getAuthToken(reviewer1.getEmail(), password); + String tokenReviewer2 = getAuthToken(reviewer2.getEmail(), password); + + // Only Admin has access to this end point + + getClient(tokenSubmitter).perform(get("/api/workflow/claimedtasks/search/findAllByItem") + .param("uuid", claimedTask1.getWorkflowItem().getItem().getID().toString())) + .andExpect(status().isForbidden()); + + getClient(tokenReviewer1).perform(get("/api/workflow/claimedtasks/search/findAllByItem") + .param("uuid", claimedTask1.getWorkflowItem().getItem().getID().toString())) + .andExpect(status().isForbidden()); + + getClient(tokenReviewer2).perform(get("/api/workflow/claimedtasks/search/findAllByItem") + .param("uuid", claimedTask1.getWorkflowItem().getItem().getID().toString())) + .andExpect(status().isForbidden()); + } + + @Test + public void findAllClaimedTaskByItemUnauthorizedTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community").build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + ClaimedTask claimedTask1 = ClaimedTaskBuilder.createClaimedTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + getClient().perform(get("/api/workflow/claimedtasks/search/findAllByItem") + .param("uuid", claimedTask1.getWorkflowItem().getItem().getID().toString())) + .andExpect(status().isUnauthorized()); + + } + + @Test + public void findAllClaimedTaskByItemWrongUUIDTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community").build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + ClaimedTask claimedTask1 = ClaimedTaskBuilder.createClaimedTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/workflow/claimedtasks/search/findAllByItem") + .param("uuid", UUID.randomUUID().toString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.claimedtasks").doesNotExist()) + .andExpect(jsonPath("$.page.totalElements", is(0))); + } + + @Test + public void findClaimedTaskByItemTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + EPerson reviewer2 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer2@example.com") + .withPassword(password).build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1, reviewer2).build(); + Collection col2 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 2") + .withWorkflowGroup(1, reviewer2).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + ClaimedTask claimedTask1 = ClaimedTaskBuilder.createClaimedTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + ClaimedTask claimedTask2 = ClaimedTaskBuilder.createClaimedTask(context, col2, reviewer2) + .withTitle("Workflow Item 2") + .withIssueDate("2020-10-19") + .withAuthor("Tommaso, Donald") + .withAuthor("Shon, John") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String reviewer1Token = getAuthToken(reviewer1.getEmail(), password); + String reviewer2Token = getAuthToken(reviewer2.getEmail(), password); + + getClient(reviewer1Token).perform(get("/api/workflow/claimedtask/search/findByItem") + .param("uuid", claimedTask1.getWorkflowItem().getItem().getID().toString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(claimedTask1.getID()))) + .andExpect(jsonPath("$.type", is("claimedtask"))) + .andExpect(jsonPath("$", Matchers.is(ClaimedTaskMatcher.matchClaimedTask(claimedTask1, "reviewstep")))) + .andExpect(jsonPath("$._embedded.workflowitem", + Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( + claimedTask1.getWorkflowItem(), "Workflow Item 1", "2017-10-17", "ExtraEntry")))); + + getClient(reviewer2Token).perform(get("/api/workflow/claimedtask/search/findByItem") + .param("uuid", claimedTask2.getWorkflowItem().getItem().getID().toString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(claimedTask2.getID()))) + .andExpect(jsonPath("$.type", is("claimedtask"))) + .andExpect(jsonPath("$", Matchers.is(ClaimedTaskMatcher.matchClaimedTask(claimedTask2, "reviewstep")))) + .andExpect(jsonPath("$._embedded.workflowitem", + Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( + claimedTask2.getWorkflowItem(), "Workflow Item 2", "2020-10-19", "ExtraEntry")))); + + } + + @Test + public void findClaimedTaskByItemNoContentTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + EPerson reviewer2 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer2@example.com") + .withPassword(password).build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1, reviewer2).build(); + Collection col2 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 2") + .withWorkflowGroup(1, reviewer2).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + ClaimedTask claimedTask1 = ClaimedTaskBuilder.createClaimedTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + ClaimedTask claimedTask2 = ClaimedTaskBuilder.createClaimedTask(context, col2, reviewer2) + .withTitle("Workflow Item 2") + .withIssueDate("2020-10-19") + .withAuthor("Tommaso, Donald") + .withAuthor("Shon, John") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String adminToken = getAuthToken(admin.getEmail(), password); + String submitterToken = getAuthToken(submitter.getEmail(), password); + String reviewer1Token = getAuthToken(reviewer1.getEmail(), password); + String reviewer2Token = getAuthToken(reviewer2.getEmail(), password); + + getClient(reviewer2Token).perform(get("/api/workflow/claimedtask/search/findByItem") + .param("uuid", claimedTask1.getWorkflowItem().getItem().getID().toString())) + .andExpect(status().isNoContent()); + + getClient(reviewer1Token).perform(get("/api/workflow/claimedtask/search/findByItem") + .param("uuid", claimedTask2.getWorkflowItem().getItem().getID().toString())) + .andExpect(status().isNoContent()); + + getClient(adminToken).perform(get("/api/workflow/claimedtask/search/findByItem") + .param("uuid", claimedTask1.getWorkflowItem().getItem().getID().toString())) + .andExpect(status().isNoContent()); + + getClient(adminToken).perform(get("/api/workflow/claimedtask/search/findByItem") + .param("uuid", claimedTask2.getWorkflowItem().getItem().getID().toString())) + .andExpect(status().isNoContent()); + + getClient(submitterToken).perform(get("/api/workflow/claimedtask/search/findByItem") + .param("uuid", claimedTask1.getWorkflowItem().getItem().getID().toString())) + .andExpect(status().isNoContent()); + + getClient(submitterToken).perform(get("/api/workflow/claimedtask/search/findByItem") + .param("uuid", claimedTask2.getWorkflowItem().getItem().getID().toString())) + .andExpect(status().isNoContent()); + + } + + @Test + public void findClaimedTaskByItemUnauthorizedTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + ClaimedTask claimedTask = ClaimedTaskBuilder.createClaimedTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + getClient().perform(get("/api/workflow/claimedtask/search/findByItem") + .param("uuid", claimedTask.getWorkflowItem().getItem().getID().toString())) + .andExpect(status().isUnauthorized()); + } + + @Test + public void findClaimedTaskByItemWrongUuidTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + ClaimedTask claimedTask = ClaimedTaskBuilder.createClaimedTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String reviewer1Token = getAuthToken(reviewer1.getEmail(), password); + getClient(reviewer1Token).perform(get("/api/workflow/claimedtask/search/findByItem") + .param("uuid", UUID.randomUUID().toString())) + .andExpect(status().isNoContent()); + } } From da9efdff6c7b6b5602ddf81bf1d345af96019716 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Mon, 16 Nov 2020 14:42:37 +0100 Subject: [PATCH 009/179] fixed search method of Pooltask endpoint --- .../repository/PoolTaskRestRepository.java | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/PoolTaskRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/PoolTaskRestRepository.java index 475a36ba31..fdda18cddd 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/PoolTaskRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/PoolTaskRestRepository.java @@ -140,12 +140,6 @@ public class PoolTaskRestRepository extends DSpaceRestRepository poolTasks = null; try { Context context = obtainContext(); - EPerson currentUser = context.getCurrentUser(); - if (currentUser == null) { - throw new RESTAuthorizationException( - "This endpoint is available only to logged-in user to search for their" - + " own claimed tasks or the admins"); - } Item item = itemService.find(context, itemUUID); if (item == null) { return null; @@ -173,19 +167,18 @@ public class PoolTaskRestRepository extends DSpaceRestRepository Date: Mon, 16 Nov 2020 14:43:17 +0100 Subject: [PATCH 010/179] fixed search method of ClaimedTask endpoint --- .../app/rest/repository/ClaimedTaskRestRepository.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java index 1361b0efd6..68903b40a3 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java @@ -142,12 +142,6 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository tasks = null; try { Context context = obtainContext(); - EPerson currentUser = context.getCurrentUser(); - if (currentUser == null) { - throw new RESTAuthorizationException( - "This endpoint is available only to logged-in user to search for their" - + " own claimed tasks or the admins"); - } Item item = itemService.find(context, itemUUID); if (item == null) { return null; @@ -185,6 +179,9 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository Date: Mon, 16 Nov 2020 15:28:25 +0100 Subject: [PATCH 011/179] added missing test --- .../app/rest/TaskRestRepositoriesIT.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java index c9091e6913..5a0c999ae6 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java @@ -3317,6 +3317,50 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(status().isForbidden()); } + @Test + public void findAllPooltasksByItemWrongUuidTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1, admin).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + PoolTask poolTask = PoolTaskBuilder.createPoolTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + Item item1 = poolTask.getWorkflowItem().getItem(); + + context.restoreAuthSystemState(); + + // Only Admin has access to this end point + + String tokenSubmitter = getAuthToken(admin.getEmail(), password); + getClient(tokenSubmitter).perform(get("/api/workflow/pooltasks/search/findAllByItem") + .param("uuid", UUID.randomUUID().toString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.pooltasks").doesNotExist()) + .andExpect(jsonPath("$.page.totalElements", is(0))); + + } @Test public void findPooltaskByItemTest() throws Exception { context.turnOffAuthorisationSystem(); From c8f5ca27893e17af145799eae2a119938b02da27 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Wed, 18 Nov 2020 09:44:01 +0100 Subject: [PATCH 012/179] refactored test, removing the double check --- .../app/rest/TaskRestRepositoriesIT.java | 240 +----------------- 1 file changed, 10 insertions(+), 230 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java index 5a0c999ae6..de9c4aa462 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java @@ -10,7 +10,6 @@ package org.dspace.app.rest; import static com.jayway.jsonpath.JsonPath.read; import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertEquals; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.fileUpload; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -30,7 +29,6 @@ import java.util.concurrent.atomic.AtomicReference; import org.dspace.app.rest.matcher.ClaimedTaskMatcher; import org.dspace.app.rest.matcher.EPersonMatcher; import org.dspace.app.rest.matcher.PoolTaskMatcher; -import org.dspace.app.rest.matcher.WorkflowActionMatcher; import org.dspace.app.rest.matcher.WorkflowItemMatcher; import org.dspace.app.rest.matcher.WorkflowStepMatcher; import org.dspace.app.rest.matcher.WorkspaceItemMatcher; @@ -1824,7 +1822,6 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String adminToken = getAuthToken(admin.getEmail(), password); AtomicReference idRef = new AtomicReference(); - AtomicReference idRefClaimedTask = new AtomicReference(); Step step = xmlWorkflowFactory.getStepByName("reviewstep"); // step 1 @@ -1851,33 +1848,10 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .content("/api/workflow/pooltasks/" + idRef.get())) .andExpect(status().isCreated()) .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) - .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); + .andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id"))); WorkflowActionConfig workflowAction = xmlWorkflowFactory.getActionByName("reviewaction"); - // get the id of the claimed task - getClient(reviewer1Token).perform(get("/api/workflow/claimedtasks/search/findByUser") - .param("uuid", reviewer1.getID().toString()).param("projection", "full")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$._embedded.claimedtasks", Matchers.contains( - Matchers.allOf( - hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), - hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.step", WorkflowStepMatcher.matchWorkflowStepEntry(step)), - hasJsonPath("$._embedded.workflowitem", - Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( - witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))), - hasJsonPath("$._embedded.action", - WorkflowActionMatcher.matchWorkflowActionEntry(workflowAction)) - )))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks"))) - .andExpect(jsonPath("$.page.size", is(20))) - .andExpect(jsonPath("$.page.totalElements", is(1))) - .andDo((result -> idRef - .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); - - assertEquals(idRefClaimedTask.get(), idRef.get()); - // approve the claimedTask, wf step 1 getClient(reviewer1Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) .param("submit_approve", "true") @@ -1915,33 +1889,10 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .content("/api/workflow/pooltasks/" + idRef.get())) .andExpect(status().isCreated()) .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) - .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); + .andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id"))); workflowAction = xmlWorkflowFactory.getActionByName("editaction"); - // get the id of the claimed task - getClient(reviewer2Token).perform(get("/api/workflow/claimedtasks/search/findByUser") - .param("uuid", reviewer2.getID().toString()).param("projection", "full")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$._embedded.claimedtasks", Matchers.contains( - Matchers.allOf( - hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), - hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.step", WorkflowStepMatcher.matchWorkflowStepEntry(step)), - hasJsonPath("$._embedded.workflowitem", - Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( - witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))), - hasJsonPath("$._embedded.action", - WorkflowActionMatcher.matchWorkflowActionEntry(workflowAction)) - )))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks"))) - .andExpect(jsonPath("$.page.size", is(20))) - .andExpect(jsonPath("$.page.totalElements", is(1))) - .andDo((result -> idRef - .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); - - assertEquals(idRefClaimedTask.get(), idRef.get()); - // approve the claimedTask, wf step 2 getClient(reviewer2Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) .param("submit_approve", "true") @@ -1979,31 +1930,9 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .content("/api/workflow/pooltasks/" + idRef.get())) .andExpect(status().isCreated()) .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) - .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); + .andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id"))); workflowAction = xmlWorkflowFactory.getActionByName("finaleditaction"); - // get the id of the claimed task - getClient(reviewer3Token).perform(get("/api/workflow/claimedtasks/search/findByUser") - .param("uuid", reviewer3.getID().toString()).param("projection", "full")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$._embedded.claimedtasks", Matchers.contains( - Matchers.allOf( - hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), - hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.step", WorkflowStepMatcher.matchWorkflowStepEntry(step)), - hasJsonPath("$._embedded.workflowitem", - Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( - witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))), - hasJsonPath("$._embedded.action", - WorkflowActionMatcher.matchWorkflowActionEntry(workflowAction)) - )))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks"))) - .andExpect(jsonPath("$.page.size", is(20))) - .andExpect(jsonPath("$.page.totalElements", is(1))) - .andDo((result -> idRef - .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); - - assertEquals(idRefClaimedTask.get(), idRef.get()); // approve the claimedTask, wf step 3 getClient(reviewer3Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) @@ -2067,7 +1996,6 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String adminToken = getAuthToken(admin.getEmail(), password); AtomicReference idRef = new AtomicReference(); - AtomicReference idRefClaimedTask = new AtomicReference(); // step 1 getClient(reviewer1Token).perform(get("/api/workflow/pooltasks/search/findByUser") @@ -2092,27 +2020,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .content("/api/workflow/pooltasks/" + idRef.get())) .andExpect(status().isCreated()) .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) - .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); - - // get the id of the claimed task - getClient(reviewer1Token).perform(get("/api/workflow/claimedtasks/search/findByUser") - .param("uuid", reviewer1.getID().toString())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$._embedded.claimedtasks", Matchers.contains( - Matchers.allOf( - hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), - hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", - Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( - witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) - )))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks"))) - .andExpect(jsonPath("$.page.size", is(20))) - .andExpect(jsonPath("$.page.totalElements", is(1))) - .andDo((result -> idRef - .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); - - assertEquals(idRefClaimedTask.get(), idRef.get()); + .andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id"))); // reject the claimedTask with reason, default wf step 1 - review step getClient(reviewer1Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) @@ -2185,7 +2093,6 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String reviewer1Token = getAuthToken(reviewer1.getEmail(), password); AtomicReference idRef = new AtomicReference(); - AtomicReference idRefClaimedTask = new AtomicReference(); // step 1 getClient(reviewer1Token).perform(get("/api/workflow/pooltasks/search/findByUser") @@ -2210,27 +2117,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .content("/api/workflow/pooltasks/" + idRef.get())) .andExpect(status().isCreated()) .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) - .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); - - // get the id of the claimed task - getClient(reviewer1Token).perform(get("/api/workflow/claimedtasks/search/findByUser") - .param("uuid", reviewer1.getID().toString())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$._embedded.claimedtasks", Matchers.contains( - Matchers.allOf( - hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), - hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", - Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( - witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) - )))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks"))) - .andExpect(jsonPath("$.page.size", is(20))) - .andExpect(jsonPath("$.page.totalElements", is(1))) - .andDo((result -> idRef - .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); - - assertEquals(idRefClaimedTask.get(), idRef.get()); + .andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id"))); // try non valid option (submit_edit_metadata), in default wf step 1 (review step) getClient(reviewer1Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) @@ -2293,7 +2180,6 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String adminToken = getAuthToken(admin.getEmail(), password); AtomicReference idRef = new AtomicReference(); - AtomicReference idRefClaimedTask = new AtomicReference(); // step 2 getClient(reviewer2Token).perform(get("/api/workflow/pooltasks/search/findByUser") @@ -2318,27 +2204,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .content("/api/workflow/pooltasks/" + idRef.get())) .andExpect(status().isCreated()) .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) - .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); - - // get the id of the claimed task - getClient(reviewer2Token).perform(get("/api/workflow/claimedtasks/search/findByUser") - .param("uuid", reviewer2.getID().toString())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$._embedded.claimedtasks", Matchers.contains( - Matchers.allOf( - hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), - hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", - Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( - witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) - )))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks"))) - .andExpect(jsonPath("$.page.size", is(20))) - .andExpect(jsonPath("$.page.totalElements", is(1))) - .andDo((result -> idRef - .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); - - assertEquals(idRefClaimedTask.get(), idRef.get()); + .andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id"))); // reject the claimedTask, default wf step 2 (edit step) getClient(reviewer2Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) @@ -2432,35 +2298,12 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .set(read(result.getResponse().getContentAsString(), "$._embedded.pooltasks[0].id")))); // claim the task -// getClient(reviewer2Token).perform(post("/api/workflow/pooltasks/" + idRef.get()) -// .contentType(MediaType.APPLICATION_FORM_URLENCODED)) -// .andExpect(status().isNoContent()); getClient(reviewer2Token).perform(post("/api/workflow/claimedtasks") .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) .content("/api/workflow/pooltasks/" + idRef.get())) .andExpect(status().isCreated()) .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) - .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); - - // get the id of the claimed task - getClient(reviewer2Token).perform(get("/api/workflow/claimedtasks/search/findByUser") - .param("uuid", reviewer2.getID().toString())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$._embedded.claimedtasks", Matchers.contains( - Matchers.allOf( - hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), - hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", - Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( - witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) - )))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks"))) - .andExpect(jsonPath("$.page.size", is(20))) - .andExpect(jsonPath("$.page.totalElements", is(1))) - .andDo((result -> idRef - .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); - - assertEquals(idRefClaimedTask.get(), idRef.get()); + .andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id"))); // try non valid option (submit_edit_metadata), default wf step 2 (edit step) getClient(reviewer2Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) @@ -2529,7 +2372,6 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String adminToken = getAuthToken(admin.getEmail(), password); AtomicReference idRef = new AtomicReference(); - AtomicReference idRefClaimedTask = new AtomicReference(); // step 3 getClient(reviewer3Token).perform(get("/api/workflow/pooltasks/search/findByUser") @@ -2554,27 +2396,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .content("/api/workflow/pooltasks/" + idRef.get())) .andExpect(status().isCreated()) .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) - .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); - - // get the id of the claimed task - getClient(reviewer3Token).perform(get("/api/workflow/claimedtasks/search/findByUser") - .param("uuid", reviewer3.getID().toString())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$._embedded.claimedtasks", Matchers.contains( - Matchers.allOf( - hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), - hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", - Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( - witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) - )))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks"))) - .andExpect(jsonPath("$.page.size", is(20))) - .andExpect(jsonPath("$.page.totalElements", is(1))) - .andDo((result -> idRef - .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); - - assertEquals(idRefClaimedTask.get(), idRef.get()); + .andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id"))); // reject the claimedTask, default wf step 3 (final edit step) getClient(reviewer3Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) @@ -2643,7 +2465,6 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String adminToken = getAuthToken(admin.getEmail(), password); AtomicReference idRef = new AtomicReference(); - AtomicReference idRefClaimedTask = new AtomicReference(); // step 3 getClient(reviewer3Token).perform(get("/api/workflow/pooltasks/search/findByUser") @@ -2668,27 +2489,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .content("/api/workflow/pooltasks/" + idRef.get())) .andExpect(status().isCreated()) .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) - .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); - - // get the id of the claimed task - getClient(reviewer3Token).perform(get("/api/workflow/claimedtasks/search/findByUser") - .param("uuid", reviewer3.getID().toString())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$._embedded.claimedtasks", Matchers.contains( - Matchers.allOf( - hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), - hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", - Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( - witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) - )))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks"))) - .andExpect(jsonPath("$.page.size", is(20))) - .andExpect(jsonPath("$.page.totalElements", is(1))) - .andDo((result -> idRef - .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); - - assertEquals(idRefClaimedTask.get(), idRef.get()); + .andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id"))); // edit metadata of the claimedTask, default wf step 3 (final edit step) getClient(reviewer3Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) @@ -2747,7 +2548,6 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String adminToken = getAuthToken(admin.getEmail(), password); AtomicReference idRef = new AtomicReference(); - AtomicReference idRefClaimedTask = new AtomicReference(); // step 3 getClient(reviewer3Token).perform(get("/api/workflow/pooltasks/search/findByUser") @@ -2772,27 +2572,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .content("/api/workflow/pooltasks/" + idRef.get())) .andExpect(status().isCreated()) .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) - .andDo(result -> idRefClaimedTask.set(read(result.getResponse().getContentAsString(), "$.id"))); - - // get the id of the claimed task - getClient(reviewer3Token).perform(get("/api/workflow/claimedtasks/search/findByUser") - .param("uuid", reviewer3.getID().toString())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$._embedded.claimedtasks", Matchers.contains( - Matchers.allOf( - hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), - hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", - Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( - witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) - )))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks"))) - .andExpect(jsonPath("$.page.size", is(20))) - .andExpect(jsonPath("$.page.totalElements", is(1))) - .andDo((result -> idRef - .set(read(result.getResponse().getContentAsString(), "$._embedded.claimedtasks[0].id")))); - - assertEquals(idRefClaimedTask.get(), idRef.get()); + .andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id"))); // non valid option in the default wf step 3 (final edit step) getClient(reviewer3Token).perform(post("/api/workflow/claimedtasks/" + idRef.get()) From 40ec8d70766a079ca7922f47e6c86ae077dd346d Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Thu, 19 Nov 2020 09:38:43 +0100 Subject: [PATCH 013/179] changed type, from Integer to int --- .../handler/ExternalSourceEntryPoolTaskUriListHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/handler/ExternalSourceEntryPoolTaskUriListHandler.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/handler/ExternalSourceEntryPoolTaskUriListHandler.java index 7d2fc08386..4ed438f93b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/handler/ExternalSourceEntryPoolTaskUriListHandler.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/handler/ExternalSourceEntryPoolTaskUriListHandler.java @@ -64,7 +64,7 @@ public class ExternalSourceEntryPoolTaskUriListHandler extends ExternalSourceEnt matcher.find(); String id = matcher.group(1); - Integer poolTaskId = Integer.parseInt(id); + int poolTaskId = Integer.parseInt(id); try { poolTask = poolTaskService.find(context, poolTaskId); } catch (SQLException e) { From 87e454a8153b4eb53fbfb36bb1469dc16c7ef7d0 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Fri, 4 Dec 2020 19:27:42 +0100 Subject: [PATCH 014/179] Implement community feedbacks --- .../app/rest/repository/ClaimedTaskRestRepository.java | 9 ++------- .../app/rest/repository/PoolTaskRestRepository.java | 9 ++------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java index 68903b40a3..c35e6f91c2 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java @@ -159,16 +159,11 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository Date: Tue, 15 Dec 2020 11:37:18 +0100 Subject: [PATCH 015/179] Implement community feedbacks --- .../app/rest/repository/ClaimedTaskRestRepository.java | 8 ++++---- .../app/rest/repository/PoolTaskRestRepository.java | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java index c35e6f91c2..7f8a79c6b9 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java @@ -144,7 +144,7 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository Date: Tue, 15 Dec 2020 11:39:39 +0100 Subject: [PATCH 016/179] added new tests and fixed old --- .../app/rest/TaskRestRepositoriesIT.java | 255 +++++++++++++++++- 1 file changed, 247 insertions(+), 8 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java index de9c4aa462..265a4895bf 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java @@ -39,6 +39,7 @@ import org.dspace.builder.ClaimedTaskBuilder; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.EPersonBuilder; +import org.dspace.builder.ItemBuilder; import org.dspace.builder.PoolTaskBuilder; import org.dspace.builder.WorkflowItemBuilder; import org.dspace.content.Collection; @@ -731,7 +732,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { getClient(adminToken).perform(post("/api/workflow/claimedtasks") .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) .content("/api/workflow/pooltasks/" + Integer.MAX_VALUE)) - .andExpect(status().isNotFound()); + .andExpect(status().isUnprocessableEntity()); } @Test @@ -3136,11 +3137,56 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String tokenSubmitter = getAuthToken(admin.getEmail(), password); getClient(tokenSubmitter).perform(get("/api/workflow/pooltasks/search/findAllByItem") .param("uuid", UUID.randomUUID().toString())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$._embedded.pooltasks").doesNotExist()) - .andExpect(jsonPath("$.page.totalElements", is(0))); + .andExpect(status().isUnprocessableEntity()); } + + @Test + public void findAllPooltasksByItemBadRequestTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1, admin).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + PoolTask poolTask = PoolTaskBuilder.createPoolTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + Item item1 = poolTask.getWorkflowItem().getItem(); + + context.restoreAuthSystemState(); + + // Only Admin has access to this end point + + String tokenSubmitter = getAuthToken(admin.getEmail(), password); + getClient(tokenSubmitter).perform(get("/api/workflow/pooltasks/search/findAllByItem") + .param("uuid", "wrongID")) + .andExpect(status().isBadRequest()); + + // the required param is no provided + getClient(tokenSubmitter).perform(get("/api/workflow/pooltasks/search/findAllByItem")) + .andExpect(status().isBadRequest()); + } + @Test public void findPooltaskByItemTest() throws Exception { context.turnOffAuthorisationSystem(); @@ -3314,10 +3360,51 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String tokenReviewer1 = getAuthToken(reviewer1.getEmail(), password); getClient(tokenReviewer1).perform(get("/api/workflow/pooltasks/search/findByItem") .param("uuid", UUID.randomUUID().toString())) - .andExpect(status().isNoContent()); + .andExpect(status().isUnprocessableEntity()); } + @Test + public void findPooltaskByItemBadRequestTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + PoolTask poolTask = PoolTaskBuilder.createPoolTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String tokenReviewer1 = getAuthToken(reviewer1.getEmail(), password); + getClient(tokenReviewer1).perform(get("/api/workflow/pooltasks/search/findByItem") + .param("uuid", "wrongID")) + .andExpect(status().isBadRequest()); + + getClient(tokenReviewer1).perform(get("/api/workflow/pooltasks/search/findByItem")) + .andExpect(status().isBadRequest()); + } + @Test public void findPooltaskByItemUnauthorizedTest() throws Exception { context.turnOffAuthorisationSystem(); @@ -3563,9 +3650,47 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String tokenAdmin = getAuthToken(admin.getEmail(), password); getClient(tokenAdmin).perform(get("/api/workflow/claimedtasks/search/findAllByItem") .param("uuid", UUID.randomUUID().toString())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$._embedded.claimedtasks").doesNotExist()) - .andExpect(jsonPath("$.page.totalElements", is(0))); + .andExpect(status().isUnprocessableEntity()); + } + + @Test + public void findAllClaimedTaskByItemBadRequestTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community").build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + ClaimedTask claimedTask1 = ClaimedTaskBuilder.createClaimedTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/workflow/claimedtasks/search/findAllByItem") + .param("uuid", "wrongID")) + .andExpect(status().isBadRequest()); + + // the required param is no provided + getClient(tokenAdmin).perform(get("/api/workflow/claimedtasks/search/findAllByItem")) + .andExpect(status().isBadRequest()); } @Test @@ -3792,6 +3917,120 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { String reviewer1Token = getAuthToken(reviewer1.getEmail(), password); getClient(reviewer1Token).perform(get("/api/workflow/claimedtask/search/findByItem") .param("uuid", UUID.randomUUID().toString())) + .andExpect(status().isUnprocessableEntity()); + } + + @Test + public void findClaimedTaskByItemBadRequestTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + ClaimedTask claimedTask = ClaimedTaskBuilder.createClaimedTask(context, col1, reviewer1) + .withTitle("Workflow Item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String reviewer1Token = getAuthToken(reviewer1.getEmail(), password); + getClient(reviewer1Token).perform(get("/api/workflow/claimedtask/search/findByItem") + .param("uuid", "wrongID")) + .andExpect(status().isBadRequest()); + + // the required param is no provided + getClient(reviewer1Token).perform(get("/api/workflow/claimedtask/search/findByItem")) + .andExpect(status().isBadRequest()); + } + + @Test + public void findClaimedTaskByItemArchivedTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + + Item publicItem = ItemBuilder.createItem(context, col1) + .withTitle("Public item") + .withIssueDate("2020-06-25") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String reviewer1Token = getAuthToken(reviewer1.getEmail(), password); + + getClient(reviewer1Token).perform(get("/api/workflow/claimedtask/search/findByItem") + .param("uuid", publicItem.getID().toString())) .andExpect(status().isNoContent()); + + } + + @Test + public void findPooltaksByItemInWorkflowWithoutPooltaskTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + EPerson reviewer = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer).build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + .withTitle("Workflow Item") + .withIssueDate("2010-04-24") + .withAuthor("Doe, John") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String tokenEperson = getAuthToken(eperson.getEmail(), password); + + getClient(tokenEperson).perform(get("/api/workflow/pooltasks/search/findByItem") + .param("uuid", witem.getItem().getID().toString())) + .andExpect(status().isNoContent()); } } From 088bcb64ce79d364ac3da39ea25429c50ccb691c Mon Sep 17 00:00:00 2001 From: Peter Nijs Date: Tue, 29 Dec 2020 13:26:19 +0100 Subject: [PATCH 017/179] 75469: The REST API should return the entitytype property --- .../app/rest/converter/ItemConverter.java | 24 +++ .../org/dspace/app/rest/model/ItemRest.java | 11 ++ .../dspace/app/rest/ItemRestRepositoryIT.java | 168 ++++++++++++++++++ 3 files changed, 203 insertions(+) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java index 4c7d93078c..ea50f82f98 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java @@ -10,17 +10,23 @@ package org.dspace.app.rest.converter; import java.sql.SQLException; import java.util.LinkedList; import java.util.List; +import java.util.UUID; import org.apache.logging.log4j.Logger; import org.dspace.app.rest.model.ItemRest; import org.dspace.app.rest.model.MetadataValueList; import org.dspace.app.rest.projection.Projection; +import org.dspace.content.Entity; +import org.dspace.content.EntityType; import org.dspace.content.Item; import org.dspace.content.MetadataField; import org.dspace.content.MetadataValue; +import org.dspace.content.service.EntityService; import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.dspace.discovery.IndexableObject; +import org.dspace.xoai.services.api.context.ContextService; +import org.dspace.xoai.services.api.context.ContextServiceException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -41,6 +47,12 @@ public class ItemConverter @Autowired private ItemService itemService; + @Autowired + private EntityService entityService; + + @Autowired + private ContextService contextService; + private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(ItemConverter.class); @Override @@ -51,6 +63,18 @@ public class ItemConverter item.setWithdrawn(obj.isWithdrawn()); item.setLastModified(obj.getLastModified()); + try { + Entity entity = entityService.findByItemId(contextService.getContext(), UUID.fromString(item.getId())); + EntityType entityType = entityService.getType(contextService.getContext(), entity); + if (entityType != null) { + item.setEntityType(entityType.getLabel()); + } + } catch (SQLException e) { + log.error("Error getting item's entity type", e); + } catch (ContextServiceException e) { + log.error("Error getting context", e); + } + return item; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java index 4b7229cab7..ce4881828a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java @@ -58,6 +58,7 @@ public class ItemRest extends DSpaceObjectRest { private boolean discoverable = false; private boolean withdrawn = false; private Date lastModified = new Date(); + private String entityType = null; @Override public String getCategory() { @@ -101,4 +102,14 @@ public class ItemRest extends DSpaceObjectRest { public void setLastModified(Date lastModified) { this.lastModified = lastModified; } + + public String getEntityType() { + return entityType; + } + + public void setEntityType(String entityType) { + if (this.entityType == null) { + this.entityType = entityType; + } + } } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java index 966441c427..3520972b85 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java @@ -12,6 +12,7 @@ import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadata; import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadataDoesNotExist; import static org.dspace.core.Constants.WRITE; +import static org.hamcrest.Matchers.emptyOrNullString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; @@ -25,6 +26,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import java.io.InputStream; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; @@ -41,6 +43,7 @@ import org.dspace.app.rest.matcher.ItemMatcher; import org.dspace.app.rest.model.ItemRest; import org.dspace.app.rest.model.MetadataRest; import org.dspace.app.rest.model.MetadataValueRest; +import org.dspace.app.rest.model.patch.AddOperation; import org.dspace.app.rest.model.patch.Operation; import org.dspace.app.rest.model.patch.ReplaceOperation; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; @@ -49,6 +52,7 @@ import org.dspace.builder.BitstreamBuilder; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.EPersonBuilder; +import org.dspace.builder.EntityTypeBuilder; import org.dspace.builder.GroupBuilder; import org.dspace.builder.ItemBuilder; import org.dspace.builder.ResourcePolicyBuilder; @@ -56,6 +60,7 @@ import org.dspace.builder.WorkspaceItemBuilder; import org.dspace.content.Bitstream; import org.dspace.content.Collection; import org.dspace.content.Community; +import org.dspace.content.EntityType; import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; import org.dspace.content.service.CollectionService; @@ -2740,5 +2745,168 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { } + @Test + public void testEntityTypePerson() throws Exception { + context.turnOffAuthorisationSystem(); + EntityType person = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); + Community community = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Collection").build(); + Item item = ItemBuilder.createItem(context, collection) + .withTitle("Author1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withPersonIdentifierLastName("Smith") + .withPersonIdentifierFirstName("Donald") + .withRelationshipType("Person") + .build(); + context.restoreAuthSystemState(); + String token = getAuthToken(eperson.getEmail(), password); + + getClient(token).perform(get("/api/core/items/" + item.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$.entityType", is("Person"))); + } + + @Test + public void testEntityTypePublication() throws Exception { + context.turnOffAuthorisationSystem(); + EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + Community community = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Collection").build(); + Item item = ItemBuilder.createItem(context, collection) + .withTitle("Publication1") + .withAuthor("Testy, TEst") + .withIssueDate("2015-01-01") + .withRelationshipType("Publication") + .build(); + context.restoreAuthSystemState(); + + String token = getAuthToken(eperson.getEmail(), password); + + getClient(token).perform(get("/api/core/items/" + item.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$.entityType", is("Publication"))); + } + + @Test + public void testEntityTypeOrgUnit() throws Exception { + context.turnOffAuthorisationSystem(); + EntityType orgUnit = EntityTypeBuilder.createEntityTypeBuilder(context, "OrgUnit").build(); + Community community = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Collection").build(); + Item item = ItemBuilder.createItem(context, collection) + .withTitle("OrgUnit1") + .withAuthor("Testy, TEst") + .withIssueDate("2015-01-01") + .withRelationshipType("OrgUnit") + .build(); + context.restoreAuthSystemState(); + + String token = getAuthToken(eperson.getEmail(), password); + + getClient(token).perform(get("/api/core/items/" + item.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$.entityType", is("OrgUnit"))); + } + + @Test + public void testEntityTypeProject() throws Exception { + context.turnOffAuthorisationSystem(); + EntityType project = EntityTypeBuilder.createEntityTypeBuilder(context, "Project").build(); + Community community = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Collection").build(); + Item item = ItemBuilder.createItem(context, collection) + .withTitle("Project1") + .withAuthor("Testy, TEst") + .withIssueDate("2015-01-01") + .withRelationshipType("Project") + .build(); + context.restoreAuthSystemState(); + + String token = getAuthToken(eperson.getEmail(), password); + + getClient(token).perform(get("/api/core/items/" + item.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$.entityType", is("Project"))); + } + + @Test + public void testEntityTypeNull() throws Exception { + context.turnOffAuthorisationSystem(); + Community community = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Collection").build(); + Item item = ItemBuilder.createItem(context, collection) + .withTitle("Unclassified item") + .withAuthor("Testy, TEst") + .withIssueDate("2015-01-01") + .build(); + context.restoreAuthSystemState(); + + String token = getAuthToken(eperson.getEmail(), password); + + getClient(token).perform(get("/api/core/items/" + item.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$.entityType", is(emptyOrNullString()))); + } + + @Test + public void testEntityTypeModification() throws Exception { + context.turnOffAuthorisationSystem(); + EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + Community community = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Collection").build(); + Item item = ItemBuilder.createItem(context, collection) + .withTitle("Publication1") + .withAuthor("Testy, TEst") + .withIssueDate("2015-01-01") + .build(); + context.restoreAuthSystemState(); + + // Verify there is no entityType yet + String token = getAuthToken(admin.getEmail(), password); + getClient(token).perform(get("/api/core/items/" + item.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$.entityType", is(emptyOrNullString()))); + + // Modify the entityType and verify the response already contains this modification + List ops = new ArrayList<>(); + List> values = new ArrayList<>(); + Map value = new HashMap<>(); + value.put("value", "Publication"); + values.add(value); + AddOperation addOperation = new AddOperation("/metadata/relationship.type", values); + ops.add(addOperation); + String patchBody = getPatchContent(ops); + getClient(token).perform(patch("/api/core/items/" + item.getID()) + .content(patchBody) + .contentType(contentType)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$.entityType", is("Publication"))); + + // Verify this modification is permanent + getClient(token).perform(get("/api/core/items/" + item.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$.entityType", is("Publication"))); + } } From a0a7226a43ac6dcb5e84eb0d38bb491509a1155e Mon Sep 17 00:00:00 2001 From: Peter Nijs Date: Wed, 30 Dec 2020 13:52:39 +0100 Subject: [PATCH 018/179] 75470: The sitemaps use a different URI dependent on the entity type --- .../org/dspace/app/sitemap/GenerateSitemaps.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/app/sitemap/GenerateSitemaps.java b/dspace-api/src/main/java/org/dspace/app/sitemap/GenerateSitemaps.java index 197d4cfceb..1fcbf92b73 100644 --- a/dspace-api/src/main/java/org/dspace/app/sitemap/GenerateSitemaps.java +++ b/dspace-api/src/main/java/org/dspace/app/sitemap/GenerateSitemaps.java @@ -33,10 +33,13 @@ import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; import org.dspace.content.Collection; import org.dspace.content.Community; +import org.dspace.content.Entity; +import org.dspace.content.EntityType; import org.dspace.content.Item; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.CollectionService; import org.dspace.content.service.CommunityService; +import org.dspace.content.service.EntityService; import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.dspace.core.LogManager; @@ -61,6 +64,7 @@ public class GenerateSitemaps { private static final ItemService itemService = ContentServiceFactory.getInstance().getItemService(); private static final ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); + private static final EntityService entityService = ContentServiceFactory.getInstance().getEntityService(); /** * Default constructor @@ -237,7 +241,15 @@ public class GenerateSitemaps { while (allItems.hasNext()) { Item i = allItems.next(); - String url = uiURLStem + "/items/" + i.getID(); + Entity entity = entityService.findByItemId(c, i.getID()); + EntityType entityType = entityService.getType(c, entity); + + String url; + if (entityType != null) { + url = uiURLStem + "/entities/" + entityType.getLabel() + "/" + i.getID(); + } else { + url = uiURLStem + "/items/" + i.getID(); + } Date lastMod = i.getLastModified(); if (makeHTMLMap) { From 42a6c2ae7973060e6bd66e0bd315084cc93d1646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Mon, 4 Jan 2021 15:11:14 +0000 Subject: [PATCH 019/179] addressing issue 3097 --- .../oai/metadataFormats/oai_openaire.xsl | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl b/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl index 23266c8309..bd1aa7c3b9 100644 --- a/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl +++ b/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl @@ -526,19 +526,30 @@ + - + - - - - - - - - + + + + + + + + + + + + + + + + + + From 1642a5598b551fac46ad20f95a39d6ac29572492 Mon Sep 17 00:00:00 2001 From: Peter Nijs Date: Tue, 5 Jan 2021 14:43:32 +0100 Subject: [PATCH 020/179] 75469: entityType property in ItemRest is read only --- .../src/main/java/org/dspace/app/rest/model/ItemRest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java index ce4881828a..263b65914f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java @@ -58,6 +58,7 @@ public class ItemRest extends DSpaceObjectRest { private boolean discoverable = false; private boolean withdrawn = false; private Date lastModified = new Date(); + @JsonProperty(access = JsonProperty.Access.READ_ONLY) private String entityType = null; @Override @@ -108,8 +109,6 @@ public class ItemRest extends DSpaceObjectRest { } public void setEntityType(String entityType) { - if (this.entityType == null) { - this.entityType = entityType; - } + this.entityType = entityType; } } From 4b13a11376c44be6b5cb487c40c6e7a64804b1b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Wed, 6 Jan 2021 13:10:53 +0000 Subject: [PATCH 021/179] support for related identifiers and alternative identifiers --- .../oai/metadataFormats/oai_openaire.xsl | 136 +++++++++++++++--- 1 file changed, 114 insertions(+), 22 deletions(-) diff --git a/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl b/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl index 23266c8309..12c675beb4 100644 --- a/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl +++ b/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl @@ -42,6 +42,15 @@ + + + + + + @@ -476,30 +485,91 @@ - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + @@ -509,6 +579,7 @@ + @@ -522,6 +593,27 @@ + + + + + + + + + + + + + + + + + + + + + @@ -1237,7 +1329,7 @@ DOI - + URL From 43893124e5b90ad21a401ec7bce9c33c32ceeeec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Thu, 7 Jan 2021 10:41:43 +0000 Subject: [PATCH 022/179] also add support for oaire:file @accessRightsURI --- .../oai/metadataFormats/oai_openaire.xsl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl b/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl index bd1aa7c3b9..613a737b02 100644 --- a/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl +++ b/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl @@ -532,14 +532,14 @@ - - + + - - - + + + @@ -1019,7 +1019,7 @@ + select="//doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:field[@name='value'and ends-with(translate(text(), $uppercase, $smallcase),'access')]/text()"/> @@ -1124,7 +1124,7 @@ - + From 1db63c92620f709bf9f9f46c452819bd4ffefa9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Thu, 7 Jan 2021 15:33:12 +0000 Subject: [PATCH 023/179] fix resolveFieldType for identifier element by forcing the first element --- .../config/crosswalks/oai/metadataFormats/oai_openaire.xsl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl b/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl index 12c675beb4..ddda1c2fdb 100644 --- a/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl +++ b/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl @@ -581,7 +581,7 @@ - + @@ -589,7 +589,7 @@ - + @@ -1373,7 +1373,7 @@ software - other research product + other research product From 567a9f0567a36cbea0f6c2529ddbf7a35c2db835 Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Fri, 15 Jan 2021 13:24:25 +0100 Subject: [PATCH 024/179] Verify the relationship is deleted Status 404 is needed for a relationship which doesn't exist --- .../repository/RelationshipRestRepository.java | 7 ++++++- .../org/dspace/app/rest/ItemRestRepositoryIT.java | 14 ++++++++++++++ .../app/rest/RelationshipRestRepositoryIT.java | 6 ++++++ .../app/rest/WorkspaceItemRestRepositoryIT.java | 13 +++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java index 1771456def..1c0fd54be0 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RelationshipRestRepository.java @@ -75,7 +75,12 @@ public class RelationshipRestRepository extends DSpaceRestRepository Date: Mon, 18 Jan 2021 15:14:07 +0100 Subject: [PATCH 025/179] added tests --- .../app/rest/TaskRestRepositoriesIT.java | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java index 265a4895bf..0afea26cbd 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java @@ -15,6 +15,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -3453,6 +3454,71 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { } + @Test + public void findPoolTaskByItemArchivedTest() throws Exception { + context.turnOffAuthorisationSystem(); + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + + Item publicItem = ItemBuilder.createItem(context, col1) + .withTitle("Public item") + .withIssueDate("2020-06-25") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String reviewer1Token = getAuthToken(reviewer1.getEmail(), password); + getClient(reviewer1Token).perform(get("/api/workflow/pooltasks/search/findByItem") + .param("uuid", publicItem.getID().toString())) + .andExpect(status().isNoContent()); + } + + @Test + public void findAllPoolTaskByItemArchivedTest() throws Exception { + context.turnOffAuthorisationSystem(); + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + + Item publicItem = ItemBuilder.createItem(context, col1) + .withTitle("Public item") + .withIssueDate("2020-06-25") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String reviewer1Token = getAuthToken(admin.getEmail(), password); + getClient(reviewer1Token).perform(get("/api/workflow/pooltasks/search/findAllByItem") + .param("uuid", publicItem.getID().toString())) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.page.totalPages", is(0))) + .andExpect(jsonPath("$.page.totalElements", is(0))); + } + @Test public void findAllClaimedTaskByItemTest() throws Exception { context.turnOffAuthorisationSystem(); @@ -3693,6 +3759,40 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(status().isBadRequest()); } + @Test + public void findAllClaimedTaskByItemArchivedTest() throws Exception { + context.turnOffAuthorisationSystem(); + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1).build(); + + Item publicItem = ItemBuilder.createItem(context, col1) + .withTitle("Public item") + .withIssueDate("2020-06-25") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String reviewer1Token = getAuthToken(admin.getEmail(), password); + getClient(reviewer1Token).perform(get("/api/workflow/claimedtasks/search/findAllByItem") + .param("uuid", publicItem.getID().toString())) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.page.totalPages", is(0))) + .andExpect(jsonPath("$.page.totalElements", is(0))); + } + @Test public void findClaimedTaskByItemTest() throws Exception { context.turnOffAuthorisationSystem(); From a56c442b1f885cd4660770a79c95fa4ee0700a86 Mon Sep 17 00:00:00 2001 From: Peter Nijs Date: Mon, 18 Jan 2021 16:18:48 +0100 Subject: [PATCH 026/179] 75924: Sitemaps performance and lowercase entityTypes --- .../dspace/app/sitemap/GenerateSitemaps.java | 50 ++++++++++++------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/sitemap/GenerateSitemaps.java b/dspace-api/src/main/java/org/dspace/app/sitemap/GenerateSitemaps.java index 1fcbf92b73..d0fe7d184c 100644 --- a/dspace-api/src/main/java/org/dspace/app/sitemap/GenerateSitemaps.java +++ b/dspace-api/src/main/java/org/dspace/app/sitemap/GenerateSitemaps.java @@ -27,22 +27,25 @@ import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; import org.dspace.content.Collection; import org.dspace.content.Community; -import org.dspace.content.Entity; -import org.dspace.content.EntityType; import org.dspace.content.Item; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.CollectionService; import org.dspace.content.service.CommunityService; -import org.dspace.content.service.EntityService; import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.dspace.core.LogManager; +import org.dspace.discovery.DiscoverQuery; +import org.dspace.discovery.DiscoverResult; +import org.dspace.discovery.SearchService; +import org.dspace.discovery.SearchServiceException; +import org.dspace.discovery.SearchUtils; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; @@ -64,7 +67,7 @@ public class GenerateSitemaps { private static final ItemService itemService = ContentServiceFactory.getInstance().getItemService(); private static final ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); - private static final EntityService entityService = ContentServiceFactory.getInstance().getEntityService(); + private static final SearchService searchService = SearchUtils.getSearchService(); /** * Default constructor @@ -241,22 +244,33 @@ public class GenerateSitemaps { while (allItems.hasNext()) { Item i = allItems.next(); - Entity entity = entityService.findByItemId(c, i.getID()); - EntityType entityType = entityService.getType(c, entity); - String url; - if (entityType != null) { - url = uiURLStem + "/entities/" + entityType.getLabel() + "/" + i.getID(); - } else { - url = uiURLStem + "/items/" + i.getID(); - } - Date lastMod = i.getLastModified(); + DiscoverQuery entityQuery = new DiscoverQuery(); + entityQuery.setQuery("search.uniqueid:\"Item-" + i.getID() + "\" and entityType:*"); + entityQuery.addSearchField("entityType"); - if (makeHTMLMap) { - html.addURL(url, lastMod); - } - if (makeSitemapOrg) { - sitemapsOrg.addURL(url, lastMod); + try { + DiscoverResult discoverResult = searchService.search(c, entityQuery); + + String url; + if (CollectionUtils.isNotEmpty(discoverResult.getIndexableObjects()) + && CollectionUtils.isNotEmpty(discoverResult.getSearchDocument(discoverResult.getIndexableObjects().get(0)).get(0).getSearchFieldValues("entityType")) + && StringUtils.isNotBlank(discoverResult.getSearchDocument(discoverResult.getIndexableObjects().get(0)).get(0).getSearchFieldValues("entityType").get(0))) + { + url = uiURLStem + "/entities/" + StringUtils.lowerCase(discoverResult.getSearchDocument(discoverResult.getIndexableObjects().get(0)).get(0).getSearchFieldValues("entityType").get(0)) + "/" + i.getID(); + } else { + url = uiURLStem + "/items/" + i.getID(); + } + Date lastMod = i.getLastModified(); + + if (makeHTMLMap) { + html.addURL(url, lastMod); + } + if (makeSitemapOrg) { + sitemapsOrg.addURL(url, lastMod); + } + } catch (SearchServiceException e) { + log.error("Failed getting entitytype through solr for item " + i.getID() + ": " + e.getMessage()); } c.uncacheEntity(i); From ca2c537d016a8fd076fb7a91a982036bdf911300 Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Mon, 18 Jan 2021 16:58:46 +0100 Subject: [PATCH 027/179] w2p-74236 Disable group selection for bitstream resource policies during submission --- .../submit/model/AccessConditionOption.java | 41 ++++++++++++++++ .../rest/model/AccessConditionOptionRest.java | 16 ------ .../UploadBitstreamAccessConditionDTO.java | 20 -------- .../SubmissionUploadRestRepository.java | 25 ---------- .../app/rest/submit/SubmissionService.java | 6 --- ...streamResourcePolicyAddPatchOperation.java | 44 ++++++----------- ...amResourcePolicyReplacePatchOperation.java | 38 ++++---------- .../impl/BitstreamResourcePolicyUtils.java | 49 +++++++++++++++++++ 8 files changed, 114 insertions(+), 125 deletions(-) create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyUtils.java diff --git a/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java b/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java index 398097a9ec..998f930e90 100644 --- a/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java +++ b/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java @@ -7,6 +7,19 @@ */ package org.dspace.submit.model; +import org.dspace.authorize.AuthorizeException; +import org.dspace.authorize.ResourcePolicy; +import org.dspace.authorize.service.AuthorizeService; +import org.dspace.content.Bitstream; +import org.dspace.core.Constants; +import org.dspace.core.Context; +import org.dspace.eperson.Group; +import org.dspace.eperson.service.GroupService; +import org.springframework.beans.factory.annotation.Autowired; + +import java.sql.SQLException; +import java.util.Date; + /** * This class represents an option available in the submission upload section to * set permission on a file. An option is defined by a name such as "open @@ -18,6 +31,13 @@ package org.dspace.submit.model; * @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it) */ public class AccessConditionOption { + + @Autowired + AuthorizeService authorizeService; + + @Autowired + GroupService groupService; + /** An unique name identifying the access contion option **/ private String name; @@ -118,4 +138,25 @@ public class AccessConditionOption { public void setSelectGroupName(String selectGroupName) { this.selectGroupName = selectGroupName; } + + public void createResourcePolicy(Context context, Bitstream b, String name, String description, + Date startDate, Date endDate) throws SQLException, AuthorizeException { + if (getHasStartDate() && startDate == null) { + throw new IllegalStateException("The access condition " + getName() + " requires a start date."); + } + if (getHasEndDate() && endDate == null) { + throw new IllegalStateException("The access condition " + getName() + " requires an end date."); + } + if (!getHasStartDate() && startDate != null) { + startDate = null; + } + if (!getHasEndDate() && endDate != null) { + endDate = null; + } + //TODO: check date limits as well + Group group = groupService.findByName(context, getGroupName()); + authorizeService.createResourcePolicy(context, b, group, null, Constants.READ, + ResourcePolicy.TYPE_CUSTOM, name, description, startDate, + endDate); + } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AccessConditionOptionRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AccessConditionOptionRest.java index 2b962cf6aa..8bdf39cf9b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AccessConditionOptionRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AccessConditionOptionRest.java @@ -38,22 +38,6 @@ public class AccessConditionOptionRest { @JsonInclude(Include.NON_NULL) private Date maxEndDate; - public UUID getGroupUUID() { - return groupUUID; - } - - public void setGroupUUID(UUID groupUuid) { - this.groupUUID = groupUuid; - } - - public UUID getSelectGroupUUID() { - return selectGroupUUID; - } - - public void setSelectGroupUUID(UUID selectGroupUuid) { - this.selectGroupUUID = selectGroupUuid; - } - public Date getMaxEndDate() { return maxEndDate; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/UploadBitstreamAccessConditionDTO.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/UploadBitstreamAccessConditionDTO.java index 120cb6a9d2..a38c469627 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/UploadBitstreamAccessConditionDTO.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/UploadBitstreamAccessConditionDTO.java @@ -30,10 +30,6 @@ public class UploadBitstreamAccessConditionDTO { private Integer id; - private UUID groupUUID; - - private UUID epersonUUID; - private String name; private String description; @@ -50,22 +46,6 @@ public class UploadBitstreamAccessConditionDTO { this.id = id; } - public UUID getGroupUUID() { - return groupUUID; - } - - public void setGroupUUID(UUID groupUUID) { - this.groupUUID = groupUUID; - } - - public UUID getEpersonUUID() { - return epersonUUID; - } - - public void setEpersonUUID(UUID epersonUUID) { - this.epersonUUID = epersonUUID; - } - public String getName() { return name; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java index 25ac640d49..664e655239 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java @@ -20,7 +20,6 @@ import org.dspace.app.rest.model.SubmissionUploadRest; import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.utils.DateMathParser; import org.dspace.core.Context; -import org.dspace.eperson.Group; import org.dspace.eperson.service.GroupService; import org.dspace.submit.model.AccessConditionOption; import org.dspace.submit.model.UploadConfiguration; @@ -96,30 +95,6 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository { - @Autowired - BitstreamService bitstreamService; @Autowired ItemService itemService; @@ -47,10 +48,7 @@ public class BitstreamResourcePolicyAddPatchOperation extends AddPatchOperation< AuthorizeService authorizeService; @Autowired - GroupService groupService; - - @Autowired - EPersonService epersonService; + UploadConfigurationService uploadConfigurationService; @Override void add(Context context, Request currentRequest, InProgressSubmission source, String path, Object value) @@ -61,6 +59,8 @@ public class BitstreamResourcePolicyAddPatchOperation extends AddPatchOperation< List bundle = itemService.getBundles(item, Constants.CONTENT_BUNDLE_NAME); ; + Collection uploadConfigsCollection = uploadConfigurationService.getMap().values(); + Iterator uploadConfigs = uploadConfigsCollection.iterator(); for (Bundle bb : bundle) { int idx = 0; for (Bitstream b : bb.getBitstreams()) { @@ -77,25 +77,9 @@ public class BitstreamResourcePolicyAddPatchOperation extends AddPatchOperation< } for (UploadBitstreamAccessConditionDTO newAccessCondition : newAccessConditions) { - String name = newAccessCondition.getName(); - String description = newAccessCondition.getDescription(); - - //TODO manage error on select group and eperson - Group group = null; - if (newAccessCondition.getGroupUUID() != null) { - group = groupService.find(context, newAccessCondition.getGroupUUID()); - } - EPerson eperson = null; - if (newAccessCondition.getEpersonUUID() != null) { - eperson = epersonService.find(context, newAccessCondition.getEpersonUUID()); - } - - Date startDate = newAccessCondition.getStartDate(); - Date endDate = newAccessCondition.getEndDate(); - authorizeService.createResourcePolicy(context, b, group, eperson, Constants.READ, - ResourcePolicy.TYPE_CUSTOM, name, description, startDate, - endDate); // TODO manage duplicate policy + BitstreamResourcePolicyUtils.findApplyResourcePolicy(context, uploadConfigs, + b, newAccessCondition); } } idx++; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyReplacePatchOperation.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyReplacePatchOperation.java index 7f0a23dbb9..d52d8dc844 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyReplacePatchOperation.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyReplacePatchOperation.java @@ -7,15 +7,15 @@ */ package org.dspace.app.rest.submit.factory.impl; +import java.util.Collection; import java.util.Date; +import java.util.Iterator; import java.util.List; -import java.util.UUID; import org.dspace.app.rest.model.ResourcePolicyRest; import org.dspace.app.rest.model.patch.LateObjectEvaluator; import org.dspace.authorize.ResourcePolicy; import org.dspace.authorize.service.AuthorizeService; -import org.dspace.authorize.service.ResourcePolicyService; import org.dspace.content.Bitstream; import org.dspace.content.Bundle; import org.dspace.content.InProgressSubmission; @@ -24,11 +24,9 @@ import org.dspace.content.service.BitstreamService; import org.dspace.content.service.ItemService; import org.dspace.core.Constants; import org.dspace.core.Context; -import org.dspace.eperson.EPerson; -import org.dspace.eperson.Group; -import org.dspace.eperson.service.EPersonService; -import org.dspace.eperson.service.GroupService; import org.dspace.services.model.Request; +import org.dspace.submit.model.UploadConfiguration; +import org.dspace.submit.model.UploadConfigurationService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -47,12 +45,7 @@ public class BitstreamResourcePolicyReplacePatchOperation extends ReplacePatchOp @Autowired AuthorizeService authorizeService; @Autowired - ResourcePolicyService resourcePolicyService; - - @Autowired - GroupService groupService; - @Autowired - EPersonService epersonService; + UploadConfigurationService uploadConfigurationService; @Override void replace(Context context, Request currentRequest, InProgressSubmission source, String path, Object value) @@ -64,6 +57,8 @@ public class BitstreamResourcePolicyReplacePatchOperation extends ReplacePatchOp List bundle = itemService.getBundles(item, Constants.CONTENT_BUNDLE_NAME); ; + Collection uploadConfigsCollection = uploadConfigurationService.getMap().values(); + Iterator uploadConfigs = uploadConfigsCollection.iterator(); for (Bundle bb : bundle) { int idx = 0; for (Bitstream b : bb.getBitstreams()) { @@ -85,27 +80,14 @@ public class BitstreamResourcePolicyReplacePatchOperation extends ReplacePatchOp if (split.length == 4) { ResourcePolicyRest newAccessCondition = evaluateSingleObject((LateObjectEvaluator) value); + String name = newAccessCondition.getName(); String description = newAccessCondition.getDescription(); - - //TODO manage error on select group and eperson - Group group = null; - if (newAccessCondition.getGroup().getUuid() != null) { - UUID uuidGroup = UUID.fromString(newAccessCondition.getGroup().getUuid()); - group = groupService.find(context, uuidGroup); - } - EPerson eperson = null; - if (newAccessCondition.getEperson().getUuid() != null) { - UUID uuidEPerson = UUID.fromString(newAccessCondition.getEperson().getUuid()); - eperson = epersonService.find(context, uuidEPerson); - } - Date startDate = newAccessCondition.getStartDate(); Date endDate = newAccessCondition.getEndDate(); - authorizeService.createResourcePolicy(context, b, group, eperson, Constants.READ, - ResourcePolicy.TYPE_CUSTOM, name, description, startDate, - endDate); // TODO manage duplicate policy + BitstreamResourcePolicyUtils.findApplyResourcePolicy(context, uploadConfigs, + b, name, description, startDate, endDate); } else { // "path": // "/sections/upload/files/0/accessConditions/0/startDate" diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyUtils.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyUtils.java new file mode 100644 index 0000000000..e6656110ce --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyUtils.java @@ -0,0 +1,49 @@ +package org.dspace.app.rest.submit.factory.impl; + +import org.dspace.app.rest.model.UploadBitstreamAccessConditionDTO; +import org.dspace.authorize.AuthorizeException; +import org.dspace.content.Bitstream; +import org.dspace.core.Context; +import org.dspace.submit.model.AccessConditionOption; +import org.dspace.submit.model.UploadConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.SQLException; +import java.util.Date; +import java.util.Iterator; + +public class BitstreamResourcePolicyUtils { + + private static final Logger log = LoggerFactory.getLogger(BitstreamResourcePolicyUtils.class); + + public static void findApplyResourcePolicy(Context context, Iterator uploadConfigs, + Bitstream b, UploadBitstreamAccessConditionDTO newAccessCondition) + throws SQLException, AuthorizeException { + String name = newAccessCondition.getName(); + String description = newAccessCondition.getDescription(); + + Date startDate = newAccessCondition.getStartDate(); + Date endDate = newAccessCondition.getEndDate(); + + findApplyResourcePolicy(context, uploadConfigs, b, name, description, startDate, endDate); + } + + public static void findApplyResourcePolicy(Context context, Iterator uploadConfigs, + Bitstream b, String name, String description, + Date startDate, Date endDate) + throws SQLException, AuthorizeException { + while (uploadConfigs + .hasNext()) { + UploadConfiguration uploadConfiguration = uploadConfigs.next(); + for (AccessConditionOption aco : uploadConfiguration.getOptions()) { + if (aco.getName().equalsIgnoreCase(name)) { + aco.createResourcePolicy(context, b, name, description, startDate, endDate); + return; + } + } + } + log.warn("no AccessCondition found or applied for bitstream " + b.getID() + + " with AccessCondition " + name); + } +} From 2dee4bd87d04e208069b0be997efd8c7a63ad969 Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Tue, 19 Jan 2021 09:07:00 +0100 Subject: [PATCH 028/179] w2p-74236 Disable group selection for bitstream resource policies during submission --- .../submit/model/AccessConditionOption.java | 10 ++-- .../UploadBitstreamAccessConditionDTO.java | 1 - .../SubmissionUploadRestRepository.java | 1 - ...streamResourcePolicyAddPatchOperation.java | 6 --- .../impl/BitstreamResourcePolicyUtils.java | 51 +++++++++++++++++-- .../rest/WorkspaceItemRestRepositoryIT.java | 3 ++ 6 files changed, 55 insertions(+), 17 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java b/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java index 998f930e90..1c13f99398 100644 --- a/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java +++ b/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java @@ -7,6 +7,9 @@ */ package org.dspace.submit.model; +import java.sql.SQLException; +import java.util.Date; + import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.ResourcePolicy; import org.dspace.authorize.service.AuthorizeService; @@ -17,9 +20,6 @@ import org.dspace.eperson.Group; import org.dspace.eperson.service.GroupService; import org.springframework.beans.factory.annotation.Autowired; -import java.sql.SQLException; -import java.util.Date; - /** * This class represents an option available in the submission upload section to * set permission on a file. An option is defined by a name such as "open @@ -148,10 +148,10 @@ public class AccessConditionOption { throw new IllegalStateException("The access condition " + getName() + " requires an end date."); } if (!getHasStartDate() && startDate != null) { - startDate = null; + throw new IllegalStateException("The access condition " + getName() + " cannot contain a start date."); } if (!getHasEndDate() && endDate != null) { - endDate = null; + throw new IllegalStateException("The access condition " + getName() + " cannot contain an end date."); } //TODO: check date limits as well Group group = groupService.findByName(context, getGroupName()); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/UploadBitstreamAccessConditionDTO.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/UploadBitstreamAccessConditionDTO.java index a38c469627..7ede7a6f8f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/UploadBitstreamAccessConditionDTO.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/UploadBitstreamAccessConditionDTO.java @@ -8,7 +8,6 @@ package org.dspace.app.rest.model; import java.util.Date; -import java.util.UUID; import org.dspace.app.rest.model.step.UploadBitstreamRest; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java index 664e655239..4a4614183b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java @@ -7,7 +7,6 @@ */ package org.dspace.app.rest.repository; -import java.sql.SQLException; import java.text.ParseException; import java.util.ArrayList; import java.util.Collection; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyAddPatchOperation.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyAddPatchOperation.java index 9bc8f2ffb6..5412991d51 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyAddPatchOperation.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyAddPatchOperation.java @@ -7,16 +7,13 @@ */ package org.dspace.app.rest.submit.factory.impl; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; -import java.util.Date; import java.util.Iterator; import java.util.List; import org.dspace.app.rest.model.UploadBitstreamAccessConditionDTO; import org.dspace.app.rest.model.patch.LateObjectEvaluator; -import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.service.AuthorizeService; import org.dspace.content.Bitstream; import org.dspace.content.Bundle; @@ -26,11 +23,8 @@ import org.dspace.content.service.ItemService; import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.services.model.Request; -import org.dspace.submit.model.AccessConditionOption; import org.dspace.submit.model.UploadConfiguration; import org.dspace.submit.model.UploadConfigurationService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; /** diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyUtils.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyUtils.java index e6656110ce..4b9a0ae133 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyUtils.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyUtils.java @@ -1,5 +1,16 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ package org.dspace.app.rest.submit.factory.impl; +import java.sql.SQLException; +import java.util.Date; +import java.util.Iterator; + import org.dspace.app.rest.model.UploadBitstreamAccessConditionDTO; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Bitstream; @@ -9,14 +20,31 @@ import org.dspace.submit.model.UploadConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.sql.SQLException; -import java.util.Date; -import java.util.Iterator; - +/** + * Utility class to reuse methods related to bitstream resource-policies + * These methods are applicable in the submission when adding or editing bitstreams, and the resource policies + * have to be applied + */ public class BitstreamResourcePolicyUtils { private static final Logger log = LoggerFactory.getLogger(BitstreamResourcePolicyUtils.class); + /** + * Default constructor + */ + private BitstreamResourcePolicyUtils() { } + + /** + * Based on the given access condition, find the resource policy to apply on the given bitstream + * This function applies the resource policies. + * + * @param context The relevant DSpace Context. + * @param uploadConfigs The configured UploadConfigurations + * @param b The applicable bitstream whose policies should be determined + * @param newAccessCondition The access condition containing the details for the desired policies + * @throws SQLException If a database error occurs + * @throws AuthorizeException If the user is not authorized + */ public static void findApplyResourcePolicy(Context context, Iterator uploadConfigs, Bitstream b, UploadBitstreamAccessConditionDTO newAccessCondition) throws SQLException, AuthorizeException { @@ -29,6 +57,21 @@ public class BitstreamResourcePolicyUtils { findApplyResourcePolicy(context, uploadConfigs, b, name, description, startDate, endDate); } + /** + * Based on the given name, find the resource policy to apply on the given bitstream + * This function applies the resource policies. + * The description, start date and end date are applied as well + * + * @param context The relevant DSpace Context. + * @param uploadConfigs The configured UploadConfigurations + * @param b The applicable bitstream whose policies should be determined + * @param name The name of the access condition matching the desired policies + * @param description An optional description for the policies + * @param startDate An optional start date for the policies + * @param endDate An optional end date for the policies + * @throws SQLException If a database error occurs + * @throws AuthorizeException If the user is not authorized + */ public static void findApplyResourcePolicy(Context context, Iterator uploadConfigs, Bitstream b, String name, String description, Date startDate, Date endDate) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java index 367013faee..7b0bbe6157 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java @@ -63,6 +63,7 @@ import org.dspace.eperson.factory.EPersonServiceFactory; import org.dspace.services.ConfigurationService; import org.hamcrest.Matchers; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockMultipartFile; @@ -3277,6 +3278,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration } @Test + @Ignore public void patchUploadAddAccessConditionTest() throws Exception { context.turnOffAuthorisationSystem(); @@ -3336,6 +3338,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration } @Test + @Ignore public void patchUploadRemoveAccessConditionTest() throws Exception { context.turnOffAuthorisationSystem(); From dd10104661ce9cf6887093674c684852c9ad167f Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Tue, 5 May 2020 11:15:27 +1200 Subject: [PATCH 029/179] [DS-3940](master) Port base SHERPA v2 changes from 6.x version --- .../org/dspace/app/sherpa/SHERPAService.java | 51 +- .../sherpa/submit/SHERPASubmitService.java | 25 +- .../app/sherpa/{ => v1}/SHERPAJournal.java | 2 +- .../app/sherpa/{ => v1}/SHERPAPublisher.java | 2 +- .../app/sherpa/{ => v1}/SHERPAResponse.java | 2 +- .../dspace/app/sherpa/v2/SHERPAJournal.java | 99 ++++ .../app/sherpa/v2/SHERPAPermittedVersion.java | 102 ++++ .../dspace/app/sherpa/v2/SHERPAPublisher.java | 81 +++ .../app/sherpa/v2/SHERPAPublisherPolicy.java | 116 ++++ .../dspace/app/sherpa/v2/SHERPAResponse.java | 533 ++++++++++++++++++ .../app/sherpa/v2/SHERPASystemMetadata.java | 69 +++ .../impl/SherpaJournalDataProvider.java | 4 +- .../impl/SherpaPublisherDataProvider.java | 4 +- 13 files changed, 1065 insertions(+), 25 deletions(-) rename dspace-api/src/main/java/org/dspace/app/sherpa/{ => v1}/SHERPAJournal.java (96%) rename dspace-api/src/main/java/org/dspace/app/sherpa/{ => v1}/SHERPAPublisher.java (99%) rename dspace-api/src/main/java/org/dspace/app/sherpa/{ => v1}/SHERPAResponse.java (99%) create mode 100644 dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAJournal.java create mode 100644 dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java create mode 100644 dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisher.java create mode 100644 dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherPolicy.java create mode 100644 dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java create mode 100644 dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPASystemMetadata.java diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java b/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java index 4cc2de7589..b254788b47 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java @@ -7,6 +7,9 @@ */ package org.dspace.app.sherpa; +import java.io.IOException; +import java.io.InputStream; + import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -16,10 +19,10 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.client.utils.URIBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.dspace.app.sherpa.v2.SHERPAResponse; import org.dspace.services.ConfigurationService; -import org.dspace.services.factory.DSpaceServicesFactory; +import org.springframework.beans.factory.annotation.Autowired; public class SHERPAService { private CloseableHttpClient client = null; @@ -28,10 +31,11 @@ public class SHERPAService { private long sleepBetweenTimeouts; private int timeout = 5000; - /** - * log4j category - */ - private static final Logger log = LogManager.getLogger(SHERPAService.class); + /** log4j category */ + private static Logger log = org.apache.logging.log4j.LogManager.getLogger(SHERPAService.class); + + @Autowired + ConfigurationService configurationService; public SHERPAService() { HttpClientBuilder builder = HttpClientBuilder.create(); @@ -45,11 +49,16 @@ public class SHERPAService { public SHERPAResponse searchByJournalISSN(String query) { - ConfigurationService configurationService - = DSpaceServicesFactory.getInstance().getConfigurationService(); - String endpoint = configurationService.getProperty("sherpa.romeo.url"); + String endpoint = configurationService.getProperty("sherpa.romeo.url", + "https://v2.sherpa.ac.uk/cgi/retrieve"); String apiKey = configurationService.getProperty("sherpa.romeo.apikey"); + // API Key is *required* for v2 API calls + if (null == apiKey) { + log.error("SHERPA ROMeO API Key missing: please register for an API key and set sherpa.romeo.apikey"); + return new SHERPAResponse("SHERPA/RoMEO configuration invalid or missing"); + } + HttpGet method = null; SHERPAResponse sherpaResponse = null; int numberOfTries = 0; @@ -70,12 +79,16 @@ public class SHERPAService { Thread.sleep(sleepBetweenTimeouts); URIBuilder uriBuilder = new URIBuilder(endpoint); - uriBuilder.addParameter("issn", query); - uriBuilder.addParameter("versions", "all"); + + uriBuilder.addParameter("item-type", "publication"); + uriBuilder.addParameter("filter", "[[\"issn\",\"equals\",\"" + query + "\"]]"); + uriBuilder.addParameter("format", "Json"); if (StringUtils.isNotBlank(apiKey)) { - uriBuilder.addParameter("ak", apiKey); + uriBuilder.addParameter("api-key", apiKey); } + log.debug("Searching SHERPA endpoint with " + uriBuilder.toString()); + method = new HttpGet(uriBuilder.build()); method.setConfig(RequestConfig.custom() .setConnectionRequestTimeout(timeout) @@ -95,12 +108,22 @@ public class SHERPAService { HttpEntity responseBody = response.getEntity(); if (null != responseBody) { - sherpaResponse = new SHERPAResponse(responseBody.getContent()); + InputStream content = null; + try { + content = responseBody.getContent(); + sherpaResponse = new SHERPAResponse(content, SHERPAResponse.SHERPAFormat.JSON); + } catch (IOException e) { + log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e); + } finally { + if (content != null) { + content.close(); + } + } } else { sherpaResponse = new SHERPAResponse("SHERPA/RoMEO returned no response"); } } catch (Exception e) { - log.warn("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e); + log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e); } finally { if (method != null) { method.releaseConnection(); diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/submit/SHERPASubmitService.java b/dspace-api/src/main/java/org/dspace/app/sherpa/submit/SHERPASubmitService.java index 44f2723539..c171367941 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/submit/SHERPASubmitService.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/submit/SHERPASubmitService.java @@ -7,14 +7,15 @@ */ package org.dspace.app.sherpa.submit; +import java.util.Iterator; import java.util.LinkedHashSet; +import java.util.LinkedList; import java.util.List; import java.util.Set; -import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; -import org.dspace.app.sherpa.SHERPAResponse; import org.dspace.app.sherpa.SHERPAService; +import org.dspace.app.sherpa.v2.SHERPAResponse; import org.dspace.content.Item; import org.dspace.core.Context; import org.dspace.core.LogManager; @@ -37,12 +38,28 @@ public class SHERPASubmitService { this.sherpaService = sherpaService; } - public SHERPAResponse searchRelatedJournals(Context context, Item item) { + public List searchRelatedJournals(Context context, Item item) { Set issns = getISSNs(context, item); if (issns == null || issns.size() == 0) { return null; } else { - return sherpaService.searchByJournalISSN(StringUtils.join(issns, ",")); + // SHERPA v2 API no longer supports "OR'd" ISSN search, perform individual searches instead + Iterator issnIterator = issns.iterator(); + List responses = new LinkedList<>(); + while (issnIterator.hasNext()) { + String issn = issnIterator.next(); + SHERPAResponse response = sherpaService.searchByJournalISSN(issn); + if (response.isError()) { + // Continue with loop + log.warn("Failed to look up SHERPA ROMeO result for ISSN: " + issn); + } + // Store this response, even if it has an error (useful for UI reporting) + responses.add(response); + } + if (responses.isEmpty()) { + responses.add(new SHERPAResponse("SHERPA ROMeO lookup failed")); + } + return responses; } } diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAJournal.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAJournal.java similarity index 96% rename from dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAJournal.java rename to dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAJournal.java index d405887da5..6cacfb8ad4 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAJournal.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAJournal.java @@ -5,7 +5,7 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.sherpa; +package org.dspace.app.sherpa.v1; /** * POJO representation for a SHERPA journal diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAPublisher.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAPublisher.java similarity index 99% rename from dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAPublisher.java rename to dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAPublisher.java index ac832db319..7f140978c3 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAPublisher.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAPublisher.java @@ -5,7 +5,7 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.sherpa; +package org.dspace.app.sherpa.v1; import java.util.List; diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAResponse.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAResponse.java similarity index 99% rename from dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAResponse.java rename to dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAResponse.java index bd2909c0c1..0e8d80ec41 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAResponse.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAResponse.java @@ -5,7 +5,7 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.sherpa; +package org.dspace.app.sherpa.v1; import java.io.InputStream; import java.util.LinkedList; diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAJournal.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAJournal.java new file mode 100644 index 0000000000..d7693a1019 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAJournal.java @@ -0,0 +1,99 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.sherpa.v2; + +import java.util.List; + +public class SHERPAJournal { + + private List titles; + private String url; + private List issns; + private String romeoPub; + private String zetoPub; + private SHERPAPublisher publisher; + private List publishers; + private List policies; + private Boolean inDOAJ; + + public SHERPAJournal() { + + } + + public List getTitles() { + return titles; + } + + public void setTitles(List titles) { + this.titles = titles; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public List getIssns() { + return issns; + } + + public void setIssns(List issns) { + this.issns = issns; + } + + public String getRomeoPub() { + return romeoPub; + } + + public void setRomeoPub(String romeoPub) { + this.romeoPub = romeoPub; + } + + public String getZetoPub() { + return zetoPub; + } + + public void setZetoPub(String zetoPub) { + this.zetoPub = zetoPub; + } + + public SHERPAPublisher getPublisher() { + return publisher; + } + + public void setPublisher(SHERPAPublisher publisher) { + this.publisher = publisher; + } + + public List getPublishers() { + return publishers; + } + + public void setPublishers(List publishers) { + this.publishers = publishers; + } + + public List getPolicies() { + return policies; + } + + public void setPolicies(List policies) { + this.policies = policies; + } + + public Boolean getInDOAJ() { + return inDOAJ; + } + + public void setInDOAJ(Boolean inDOAJ) { + this.inDOAJ = inDOAJ; + } +} diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java new file mode 100644 index 0000000000..9d18a87bb7 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java @@ -0,0 +1,102 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.sherpa.v2; + +import java.util.List; + +public class SHERPAPermittedVersion { + + // Version (submitted, accepted, published) + private String articleVersion; + + // Version label + private String articleVersionLabel; + + // Option number + private int option; + + // General conditions + private List conditions; + // Prerequisites (eg. if required by funder) + private List prerequisites; + // Allowed locations + private List locations; + // Required license(s) + private List licenses; + // Embargo + private SHERPAEmbargo embargo; + + protected class SHERPAEmbargo { + String units; + int amount; + } + + public String getArticleVersion() { + return articleVersion; + } + + public void setArticleVersion(String articleVersion) { + this.articleVersion = articleVersion; + } + + public List getConditions() { + return conditions; + } + + public void setConditions(List conditions) { + this.conditions = conditions; + } + + public List getPrerequisites() { + return prerequisites; + } + + public void setPrerequisites(List prerequisites) { + this.prerequisites = prerequisites; + } + + public List getLocations() { + return locations; + } + + public void setLocations(List locations) { + this.locations = locations; + } + + public List getLicenses() { + return licenses; + } + + public void setLicenses(List licenses) { + this.licenses = licenses; + } + + public SHERPAEmbargo getEmbargo() { + return embargo; + } + + public void setEmbargo(SHERPAEmbargo embargo) { + this.embargo = embargo; + } + + public int getOption() { + return option; + } + + public void setOption(int option) { + this.option = option; + } + + public String getArticleVersionLabel() { + return articleVersionLabel; + } + + public void setArticleVersionLabel(String articleVersionLabel) { + this.articleVersionLabel = articleVersionLabel; + } +} diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisher.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisher.java new file mode 100644 index 0000000000..e501bf351e --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisher.java @@ -0,0 +1,81 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.sherpa.v2; + +public class SHERPAPublisher { + private String name; + private String relationshipType; + private String country; + private String uri; + private int publicationCount; + + // this is not technically in the same place in SHERPA data model but it makes more sense to apply it here + // is it is treated as a 'special case' - just for printing links to paid OA access policies + private String paidAccessDescription; + private String paidAccessUrl; + + public SHERPAPublisher() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getRelationshipType() { + return relationshipType; + } + + public void setRelationshipType(String relationshipType) { + this.relationshipType = relationshipType; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public int getPublicationCount() { + return publicationCount; + } + + public void setPublicationCount(int publicationCount) { + this.publicationCount = publicationCount; + } + + public String getPaidAccessDescription() { + return paidAccessDescription; + } + + public void setPaidAccessDescription(String paidAccessDescription) { + this.paidAccessDescription = paidAccessDescription; + } + + public String getPaidAccessUrl() { + return paidAccessUrl; + } + + public void setPaidAccessUrl(String paidAccessUrl) { + this.paidAccessUrl = paidAccessUrl; + } + +} diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherPolicy.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherPolicy.java new file mode 100644 index 0000000000..5502389bb2 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherPolicy.java @@ -0,0 +1,116 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.sherpa.v2; + +import java.util.List; +import java.util.Map; + +public class SHERPAPublisherPolicy { + + private int id; + private boolean openAccessPermitted; + private String uri; + private String internalMoniker; + private List permittedVersions; + private Map urls; + private boolean openAccessProhibited; + private int publicationCount; + + // The legacy "can" / "cannot" indicators + private String preArchiving = "cannot"; + private String postArchiving = "cannot"; + private String pubArchiving = "cannot"; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public boolean isOpenAccessPermitted() { + return openAccessPermitted; + } + + public void setOpenAccessPermitted(boolean openAccessPermitted) { + this.openAccessPermitted = openAccessPermitted; + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public String getInternalMoniker() { + return internalMoniker; + } + + public void setInternalMoniker(String internalMoniker) { + this.internalMoniker = internalMoniker; + } + + public List getPermittedVersions() { + return permittedVersions; + } + + public void setPermittedVersions(List permittedVersions) { + this.permittedVersions = permittedVersions; + } + + public Map getUrls() { + return urls; + } + + public void setUrls(Map urls) { + this.urls = urls; + } + + public boolean isOpenAccessProhibited() { + return openAccessProhibited; + } + + public void setOpenAccessProhibited(boolean openAccessProhibited) { + this.openAccessProhibited = openAccessProhibited; + } + + public int getPublicationCount() { + return publicationCount; + } + + public void setPublicationCount(int publicationCount) { + this.publicationCount = publicationCount; + } + + public String getPreArchiving() { + return preArchiving; + } + + public void setPreArchiving(String preArchiving) { + this.preArchiving = preArchiving; + } + + public String getPostArchiving() { + return postArchiving; + } + + public void setPostArchiving(String postArchiving) { + this.postArchiving = postArchiving; + } + + public String getPubArchiving() { + return pubArchiving; + } + + public void setPubArchiving(String pubArchiving) { + this.pubArchiving = pubArchiving; + } +} diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java new file mode 100644 index 0000000000..89665920e0 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java @@ -0,0 +1,533 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.sherpa.v2; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.apache.log4j.Logger; +import org.dspace.core.I18nUtil; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; + +/** + * Model class for the SHERPAv2 API (JSON) response + * The structure and approached used is quite different to the simple v1 API used previously + * + * @author Kim Shepherd + * + */ +public class SHERPAResponse { + // Is this response to be treated as an error? + private boolean error; + + // Error message + private String message; + + // Parsed system metadata from search results + private SHERPASystemMetadata metadata; + + // List of parsed journal results + private List journals; + + // Internal Sherpa ID + private int id; + + // SHERPA URI (the human page version of this API response) + private String uri; + + // Format enum - currently only JSON is supported + public enum SHERPAFormat { + JSON, XML + }; + + private static Logger log = Logger.getLogger(SHERPAResponse.class); + + /** + * Parse SHERPA v2 API for a given format + * @param input - input stream from the HTTP response content + * @param format - requested format + * @throws IOException + */ + public SHERPAResponse(InputStream input, SHERPAFormat format) throws IOException { + if (format == SHERPAFormat.JSON) { + parseJSON(input); + } + } + + /** + * Parse the SHERPA v2 API JSON and construct Romeo policy data for display + * This method does not return a value, but rather populates the metadata and journals objects + * with data parsed from the JSON. + * @param jsonData - the JSON input stream from the API result response body + */ + private void parseJSON(InputStream jsonData) throws IOException { + InputStreamReader streamReader = new InputStreamReader(jsonData); + JSONTokener jsonTokener = new JSONTokener(streamReader); + JSONObject httpResponse; + try { + httpResponse = new JSONObject(jsonTokener); + if (httpResponse.has("items")) { + JSONArray items = httpResponse.getJSONArray("items"); + + // items array is search results, *not* journals or publishers - they are listed for each item + // - however, we only ever want one result since we're passing an "equals ISSN" query + if (items.length() > 0) { + metadata = new SHERPASystemMetadata(); + this.journals = new LinkedList<>(); + // Iterate search result items + for (int itemIndex = 0; itemIndex < items.length(); itemIndex++) { + List sherpaPublishers = new LinkedList<>(); + List policies = new ArrayList<>(); + SHERPAPublisher sherpaPublisher = new SHERPAPublisher(); + SHERPAJournal sherpaJournal = new SHERPAJournal(); + + JSONObject item = items.getJSONObject(0); + + // Parse system metadata (per-item / result information) + if (item.has("system_metadata")) { + JSONObject systemMetadata = item.getJSONObject("system_metadata"); + metadata = parseSystemMetadata(systemMetadata); + } + + // Parse "publisher policy" + // note - most of the information that was previously under 'publisher' is now under here + if (item.has("publisher_policy")) { + + // Parse main publisher policies node + JSONArray publisherPolicies = item.getJSONArray("publisher_policy"); + for (int i = 0; i < publisherPolicies.length(); i++) { + + JSONObject policy = publisherPolicies.getJSONObject(i); + + // Special case - quickly check the policy for the 'paid access' option + // and continue if found, then parse the rest of the policy + String moniker = null; + if (policy.has("internal_moniker")) { + moniker = policy.getString("internal_moniker"); + } + // This seems to be usually policy(ies) for the journal proper + // and then an "Open access option" which contains some of the info + // that the 'paidaccess' node in the old API used to contain + // Look for: internal_moniker = "Open access option" + // Check if this is OA options (Paid Access) or not + if ("Open access option".equalsIgnoreCase(moniker)) { + log.debug("This is the Open access options policy - a special case"); + if (policy.has("urls")) { + JSONArray urls = policy.getJSONArray("urls"); + for (int u = 0; u < urls.length(); u++) { + JSONObject url = urls.getJSONObject(u); + if (url.has("description") && + "Open Access".equalsIgnoreCase(url.getString("description"))) { + log.debug("Found OA paid access url: " + url.getString("url")); + sherpaPublisher.setPaidAccessDescription(url.getString("description")); + sherpaPublisher.setPaidAccessUrl(url.getString("url")); + break; + } + } + } + // Continue the loop here - this "policy" is a bit different and we + // don't want to add irrelevant conditions to the policy + continue; + } + + // Parse the main publisher policy object and add to the list + SHERPAPublisherPolicy sherpaPublisherPolicy = parsePublisherPolicy(policy); + policies.add(sherpaPublisherPolicy); + } + + // set publisher name - note we're only looking for the first name here + // as per previous functionality (for simple display) + if (item.has("publishers")) { + JSONArray publishers = item.getJSONArray("publishers"); + if (publishers.length() > 0) { + JSONObject publisherElement = publishers.getJSONObject(0); + if (publisherElement.has("publisher")) { + JSONObject publisher = publisherElement.getJSONObject("publisher"); + sherpaPublisher.setName(parsePublisherName(publisher)); + sherpaPublisher.setUri(parsePublisherURL(publisher)); + } + } + } + + // Parse journal data + sherpaJournal = parseJournal(item, sherpaPublisher.getName()); + } + + sherpaPublishers.add(sherpaPublisher); + sherpaJournal.setPublisher(sherpaPublisher); + sherpaJournal.setPublishers(sherpaPublishers); + sherpaJournal.setPolicies(policies); + this.journals.add(sherpaJournal); + } + + } else { + error = true; + message = "No results found"; + } + } else { + error = true; + message = "No results found"; + } + + } catch (JSONException e) { + log.error("Failed to parse SHERPA response", e); + error = true; + } finally { + streamReader.close(); + } + } + + /** + * Parse system metadata and return populated SHERPASystemMetadata object + * @param systemMetadata + */ + private SHERPASystemMetadata parseSystemMetadata(JSONObject systemMetadata) { + + SHERPASystemMetadata metadata = new SHERPASystemMetadata(); + + if (systemMetadata.has("uri")) { + this.uri = systemMetadata.getString("uri"); + metadata.setUri(this.uri); + } else { + log.error("SHERPA URI missing for API response item"); + } + if (systemMetadata.has("id")) { + this.id = systemMetadata.getInt("id"); + metadata.setId(this.id); + } else { + log.error("SHERPA internal ID missing for API response item"); + } + // Get date created and added - DSpace expects this in the publisher object, though + if (systemMetadata.has("date_created")) { + metadata.setDateCreated(systemMetadata.getString("date_created")); + } + if (systemMetadata.has("date_modified")) { + metadata.setDateModified(systemMetadata.getString("date_modified")); + } + // Is this item publicly visible? + if (systemMetadata.has("publicly_visible")) { + metadata.setPubliclyVisible ("yes".equals(systemMetadata + .getString("publicly_visible"))); + } + // Is this item listed in the DOAJ? + if (systemMetadata.has("listed_in_doaj")) { + metadata.setPubliclyVisible ("yes".equals(systemMetadata + .getString("listed_in_doaj"))); + } + + return metadata; + } + + /** + * Parse journal JSON data and return populated bean + * This method also takes publisherName as a string to help construct some + * legacy labels + * @param item - the main result item JSON (which is the closest thing to an actual 'journal') + * @param publisherName - the parsed publisher name + * @return + */ + private SHERPAJournal parseJournal(JSONObject item, String publisherName) { + + SHERPAJournal sherpaJournal = new SHERPAJournal(); + + // set journal title + if (item.has("title")) { + JSONArray titles = item.getJSONArray("title"); + if (titles.length() > 0) { + List titleList = new ArrayList<>(); + for (int t = 0; t < titles.length(); t++) { + JSONObject title = titles.getJSONObject(t); + if (title.has("title")) { + titleList.add(title.getString("title").trim()); + } + } + sherpaJournal.setTitles(titleList); + if (titleList.size() > 0) { + // Faking this a bit based on what I'd seen - not in the API v2 data + sherpaJournal.setRomeoPub(publisherName + ": " + + titleList.get(0)); + sherpaJournal.setZetoPub(publisherName + ": " + + titleList.get(0)); + } + } + } + + // Journal URL + if (item.has("url")) { + sherpaJournal.setUrl(item.getString("url")); + } + + // set ISSNs + if (item.has("issns")) { + JSONArray issns = item.getJSONArray("issns"); + // just get first - DSpace data model only allows for one + List issnList = new ArrayList<>(); + for (int ii = 0; ii < issns.length(); ii++) { + JSONObject issn = issns.getJSONObject(ii); + issnList.add(issn.getString("issn").trim()); + } + sherpaJournal.setIssns(issnList); + } + + // Is the item in DOAJ? + if (item.has("listed_in_doaj")) { + sherpaJournal.setInDOAJ(("yes".equals(item.getString("listed_in_doaj")))); + } + + return sherpaJournal; + } + + /** + * Parse a publisher_policy JSON data and return a populated bean + * @param policy - each publisher policy node in the JSON array + * @return populated SHERPAPublisherPolicy object + */ + private SHERPAPublisherPolicy parsePublisherPolicy(JSONObject policy) { + + SHERPAPublisherPolicy sherpaPublisherPolicy = new SHERPAPublisherPolicy(); + + // Get and set monikers + String moniker = null; + if (policy.has("internal_moniker")) { + moniker = policy.getString("internal_moniker"); + sherpaPublisherPolicy.setInternalMoniker(moniker); + } + + // URLs (used to be Copyright Links) + if (policy.has("urls")) { + JSONArray urls = policy.getJSONArray("urls"); + Map copyrightLinks = new TreeMap<>(); + for (int u = 0; u < urls.length(); u++) { + JSONObject url = urls.getJSONObject(u); + if (url.has("description") && url.has("url")) { + log.debug("Setting copyright URL: " + url.getString("url")); + copyrightLinks.put(url.getString("url"), url.getString("description")); + } + } + sherpaPublisherPolicy.setUrls(copyrightLinks); + } + + // Permitted OA options + int submittedOption = 0; + int acceptedOption = 0; + int publishedOption = 0; + int currentOption = 0; + if (policy.has("permitted_oa")) { + List allowed = new ArrayList<>(); + JSONArray permittedOA = policy.getJSONArray("permitted_oa"); + List permittedVersions = new ArrayList<>(); + + // Iterate each permitted OA version / option + for (int p = 0; p < permittedOA.length(); p++) { + JSONObject permitted = permittedOA.getJSONObject(p); + SHERPAPermittedVersion permittedVersion = parsePermittedVersion(permitted); + + // To determine which option # we are, inspect article versions and set + allowed.add(permittedVersion.getArticleVersion()); + if ("submitted".equals(permittedVersion.getArticleVersion())) { + submittedOption++; + currentOption = submittedOption; + } else if ("accepted".equals(permittedVersion.getArticleVersion())) { + acceptedOption++; + currentOption = acceptedOption; + } else if ("published".equals(permittedVersion.getArticleVersion())) { + publishedOption++; + currentOption = publishedOption; + } + permittedVersion.setOption(currentOption); + permittedVersions.add(permittedVersion); + + // Populate the old indicators into the publisher policy object + if (allowed.contains("submitted")) { + sherpaPublisherPolicy.setPreArchiving("can"); + } + if (allowed.contains("accepted")) { + sherpaPublisherPolicy.setPostArchiving("can"); + } + if (allowed.contains("published")) { + sherpaPublisherPolicy.setPubArchiving("can"); + } + + } + sherpaPublisherPolicy.setPermittedVersions(permittedVersions); + } + + return sherpaPublisherPolicy; + } + + /** + * Parse permitted version JSON and populate new bean from the data + * @param permitted - each 'permitted_oa' node in the JSON array + * @return populated SHERPAPermittedVersion object + */ + private SHERPAPermittedVersion parsePermittedVersion(JSONObject permitted) { + + SHERPAPermittedVersion permittedVersion = new SHERPAPermittedVersion(); + + // Get the article version, which is ultimately used for the ticks / crosses + // in the UI display. My assumptions around translation: + // submitted = preprint + // accepted = postprint + // published = pdfversion + String articleVersion = "unknown"; + String versionLabel = "Unknown"; + + if (permitted.has("article_version")) { + JSONArray versions = permitted.getJSONArray("article_version"); + articleVersion = versions.getString(0); + permittedVersion.setArticleVersion(articleVersion); + log.debug("Added allowed version: " + articleVersion + " to list"); + } + + if ("submitted".equals(articleVersion)) { + versionLabel = I18nUtil.getMessage("jsp.sherpa.submitted-version-label"); + } else if ("accepted".equals(articleVersion)) { + versionLabel = I18nUtil.getMessage("jsp.sherpa.accepted-version-label"); + } else if ("published".equals(articleVersion)) { + versionLabel = I18nUtil.getMessage("jsp.sherpa.published-version-label"); + } + + // These are now child arrays, in old API they were explicit like + // "preprint restrictions", etc., and just contained text rather than data + if (permitted.has("conditions")) { + List conditionList = new ArrayList<>(); + JSONArray conditions = permitted.getJSONArray("conditions"); + for (int c = 0; c < conditions.length(); c++) { + conditionList.add(conditions.getString(c).trim()); + } + permittedVersion.setConditions(conditionList); + } + + permittedVersion.setArticleVersionLabel(versionLabel); + + // Any prerequisites for this option (eg required by funder) + List prerequisites = new ArrayList<>(); + if (permitted.has("prerequisites")) { + JSONObject prereqs = permitted.getJSONObject("prerequisites"); + if (prereqs.has("prerequisites_phrases")) { + JSONArray phrases = prereqs.getJSONArray("prerequisites_phrases"); + for (int pp = 0; pp < phrases.length(); pp++) { + JSONObject phrase = phrases.getJSONObject(pp); + if (phrase.has("phrase")) { + prerequisites.add(phrase.getString("phrase").trim()); + } + } + } + } + permittedVersion.setPrerequisites(prerequisites); + + // Locations where this version / option may be archived + List sherpaLocations = new ArrayList<>(); + if (permitted.has("location")) { + JSONObject locations = permitted.getJSONObject("location"); + if (locations.has("location_phrases")) { + JSONArray locationPhrases = locations.getJSONArray("location_phrases"); + if (locationPhrases.length() > 0) { + for (int l = 0; l < locationPhrases.length(); l++) { + JSONObject locationPhrase = locationPhrases.getJSONObject(l); + if (locationPhrase.has("phrase")) { + sherpaLocations.add(locationPhrase.getString("phrase").trim()); + } + } + } + } + } + permittedVersion.setLocations(sherpaLocations); + + List sherpaLicenses = new ArrayList<>(); + // required licences + if (permitted.has("license")) { + JSONArray licences = permitted.getJSONArray("license"); + for (int l = 0; l < licences.length(); l++) { + JSONObject licence = licences.getJSONObject(l); + if (licence.has("license_phrases")) { + JSONArray phrases = licence.getJSONArray("license_phrases"); + for (int ll = 0; ll < phrases.length(); ll++) { + JSONObject phrase = phrases.getJSONObject(ll); + if (phrase.has("phrase")) { + sherpaLicenses.add(phrase.getString("phrase").trim()); + } + } + } + } + } + permittedVersion.setLicenses(sherpaLicenses); + + return permittedVersion; + } + + /** + * Parse publisher array and return the first name string found + * @param publisher - array of publisher JSON data + * @return first publisher name found (trimmed String) + */ + private String parsePublisherName(JSONObject publisher) { + String name = null; + if (publisher.has("name")) { + JSONArray publisherNames = publisher.getJSONArray("name"); + if (publisherNames.length() > 0) { + JSONObject publisherName = publisherNames.getJSONObject(0); + if (publisherName.has("name")) { + name = publisherName.getString("name").trim(); + } + } + } + return name; + } + + + /** + * Parse publisher URL from the json data + * @param publisher - publisher object (from JSON array) + * @return publisher URL as string + */ + private String parsePublisherURL(JSONObject publisher) { + if (publisher.has("url")) { + return publisher.getString("url"); + } + return null; + } + + /** + * Create new response object to be handled as an error + * @param message - the message to render in logs or error pages + */ + public SHERPAResponse(String message) { + this.message = message; + this.error = true; + } + + public boolean isError() { + return error; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public List getJournals() { + return journals; + } + + public SHERPASystemMetadata getMetadata() { + return metadata; + } +} diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPASystemMetadata.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPASystemMetadata.java new file mode 100644 index 0000000000..c79eb81d4d --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPASystemMetadata.java @@ -0,0 +1,69 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.sherpa.v2; + +public class SHERPASystemMetadata { + + private int id; + private String uri; + private String dateCreated; + private String dateModified; + private boolean isPubliclyVisible = false; + private boolean inDOAJ = false; + + public SHERPASystemMetadata() { + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public String getDateCreated() { + return dateCreated; + } + + public void setDateCreated(String dateCreated) { + this.dateCreated = dateCreated; + } + + public String getDateModified() { + return dateModified; + } + + public void setDateModified(String dateModified) { + this.dateModified = dateModified; + } + + public boolean isPubliclyVisible() { + return isPubliclyVisible; + } + + public void setPubliclyVisible(boolean publiclyVisible) { + isPubliclyVisible = publiclyVisible; + } + + public boolean isInDOAJ() { + return inDOAJ; + } + + public void setInDOAJ(boolean inDOAJ) { + this.inDOAJ = inDOAJ; + } +} diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaJournalDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaJournalDataProvider.java index 349c04b434..dc5a642458 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaJournalDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaJournalDataProvider.java @@ -27,8 +27,8 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.message.BasicNameValuePair; import org.apache.logging.log4j.Logger; -import org.dspace.app.sherpa.SHERPAJournal; -import org.dspace.app.sherpa.SHERPAResponse; +import org.dspace.app.sherpa.v1.SHERPAJournal; +import org.dspace.app.sherpa.v1.SHERPAResponse; import org.dspace.content.dto.MetadataValueDTO; import org.dspace.external.model.ExternalDataObject; import org.dspace.external.provider.ExternalDataProvider; diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaPublisherDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaPublisherDataProvider.java index 4c4968057c..c13fe0a675 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaPublisherDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaPublisherDataProvider.java @@ -23,8 +23,8 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.message.BasicNameValuePair; import org.apache.logging.log4j.Logger; -import org.dspace.app.sherpa.SHERPAPublisher; -import org.dspace.app.sherpa.SHERPAResponse; +import org.dspace.app.sherpa.v1.SHERPAPublisher; +import org.dspace.app.sherpa.v1.SHERPAResponse; import org.dspace.content.dto.MetadataValueDTO; import org.dspace.external.model.ExternalDataObject; import org.dspace.external.provider.ExternalDataProvider; From dcca10c91a5e6e65f13047f8fc769a878e82c4eb Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Tue, 5 May 2020 11:35:45 +1200 Subject: [PATCH 030/179] [DS-3940](master) Refactor external providers for journals, publishers --- .../dspace/app/sherpa/v2/SHERPAPublisher.java | 12 +- .../sherpa/v2/SHERPAPublisherResponse.java | 221 +++++++++++ .../dspace/app/sherpa/v2/SHERPAResponse.java | 2 +- .../impl/SHERPAv2JournalDataProvider.java | 357 +++++++++++++++++ .../impl/SHERPAv2PublisherDataProvider.java | 360 ++++++++++++++++++ 5 files changed, 949 insertions(+), 3 deletions(-) create mode 100644 dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponse.java create mode 100644 dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java create mode 100644 dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisher.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisher.java index e501bf351e..d874e00434 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisher.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisher.java @@ -8,10 +8,11 @@ package org.dspace.app.sherpa.v2; public class SHERPAPublisher { - private String name; + private String name = null; private String relationshipType; private String country; - private String uri; + private String uri = null; + private String identifier = null; private int publicationCount; // this is not technically in the same place in SHERPA data model but it makes more sense to apply it here @@ -78,4 +79,11 @@ public class SHERPAPublisher { this.paidAccessUrl = paidAccessUrl; } + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } } diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponse.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponse.java new file mode 100644 index 0000000000..054600ab68 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponse.java @@ -0,0 +1,221 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.sherpa.v2; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.LinkedList; +import java.util.List; + +import org.apache.log4j.Logger; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; + +/** + * Model class for the SHERPAv2 API (JSON) response for a publisher search + * The structure and approached used is quite different to the simple v1 API used previously + * + * @author Kim Shepherd + * + */ +public class SHERPAPublisherResponse { + // Is this response to be treated as an error? + private boolean error; + + // Error message + private String message; + + // Parsed system metadata from search results + private SHERPASystemMetadata metadata; + + // List of parsed publisher results + private List publishers; + + // Internal Sherpa ID + private int id; + + // SHERPA URI (the human page version of this API response) + private String uri; + + // Format enum - currently only JSON is supported + public enum SHERPAFormat { + JSON, XML + }; + + private static Logger log = Logger.getLogger(SHERPAPublisherResponse.class); + + /** + * Parse SHERPA v2 API for a given format + * @param input - input stream from the HTTP response content + * @param format - requested format + * @throws IOException + */ + public SHERPAPublisherResponse(InputStream input, SHERPAFormat format) throws IOException { + if (format == SHERPAFormat.JSON) { + parseJSON(input); + } + } + + /** + * Parse the SHERPA v2 API JSON and construct simple list of publisher objects + * This method does not return a value, but rather populates the metadata and publishers objects + * with data parsed from the JSON. + * @param jsonData - the JSON input stream from the API result response body + */ + private void parseJSON(InputStream jsonData) throws IOException { + InputStreamReader streamReader = new InputStreamReader(jsonData); + JSONTokener jsonTokener = new JSONTokener(streamReader); + JSONObject httpResponse; + try { + httpResponse = new JSONObject(jsonTokener); + if (httpResponse.has("items")) { + JSONArray items = httpResponse.getJSONArray("items"); + + // items array in this context is publisher results - parsing is more simple than + // parsing the full journal / policy responses + if (items.length() > 0) { + metadata = new SHERPASystemMetadata(); + this.publishers = new LinkedList<>(); + // Iterate search result items + for (int itemIndex = 0; itemIndex < items.length(); itemIndex++) { + SHERPAPublisher sherpaPublisher = new SHERPAPublisher(); + + JSONObject item = items.getJSONObject(0); + + // Parse system metadata (per-item / result information) + if (item.has("system_metadata")) { + JSONObject systemMetadata = item.getJSONObject("system_metadata"); + metadata = parseSystemMetadata(systemMetadata); + if (metadata.getId() >= 0) { + // Set publisher identifier to be the internal SHERPA ID + // eg. '30' (Elsevier) + sherpaPublisher.setIdentifier(String.valueOf(metadata.getId())); + } + } + + // Set publisher name + sherpaPublisher.setName(parsePublisherName(item)); + + // Set publisher URL + sherpaPublisher.setUri(parsePublisherURL(item)); + + this.publishers.add(sherpaPublisher); + } + + } else { + error = true; + message = "No results found"; + } + } else { + error = true; + message = "No results found"; + } + + } catch (JSONException e) { + log.error("Failed to parse SHERPA response", e); + error = true; + } finally { + streamReader.close(); + } + } + + /** + * Parse system metadata and return populated SHERPASystemMetadata object + * @param systemMetadata + */ + private SHERPASystemMetadata parseSystemMetadata(JSONObject systemMetadata) { + + SHERPASystemMetadata metadata = new SHERPASystemMetadata(); + + if (systemMetadata.has("uri")) { + this.uri = systemMetadata.getString("uri"); + metadata.setUri(this.uri); + } else { + log.error("SHERPA URI missing for API response item"); + } + if (systemMetadata.has("id")) { + this.id = systemMetadata.getInt("id"); + metadata.setId(this.id); + } else { + log.error("SHERPA internal ID missing for API response item"); + } + // Get date created and added - DSpace expects this in the publisher object, though + if (systemMetadata.has("date_created")) { + metadata.setDateCreated(systemMetadata.getString("date_created")); + } + if (systemMetadata.has("date_modified")) { + metadata.setDateModified(systemMetadata.getString("date_modified")); + } + + return metadata; + } + + /** + * Parse publisher array and return the first name string found + * @param publisher - array of publisher JSON data + * @return first publisher name found (trimmed String) + */ + private String parsePublisherName(JSONObject publisher) { + String name = null; + if (publisher.has("name")) { + JSONArray publisherNames = publisher.getJSONArray("name"); + if (publisherNames.length() > 0) { + JSONObject publisherName = publisherNames.getJSONObject(0); + if (publisherName.has("name")) { + name = publisherName.getString("name").trim(); + } + } + } + return name; + } + + + /** + * Parse publisher URL from the json data + * @param publisher - publisher object (from JSON array) + * @return publisher URL as string + */ + private String parsePublisherURL(JSONObject publisher) { + if (publisher.has("url")) { + return publisher.getString("url"); + } + return null; + } + + /** + * Create new response object to be handled as an error + * @param message - the message to render in logs or error pages + */ + public SHERPAPublisherResponse(String message) { + this.message = message; + this.error = true; + } + + public boolean isError() { + return error; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public SHERPASystemMetadata getMetadata() { + return metadata; + } + + public List getPublishers() { + return publishers; + } +} diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java index 89665920e0..34208ff788 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java @@ -24,7 +24,7 @@ import org.json.JSONObject; import org.json.JSONTokener; /** - * Model class for the SHERPAv2 API (JSON) response + * Model class for the SHERPAv2 API (JSON) response for a publication (journal) search * The structure and approached used is quite different to the simple v1 API used previously * * @author Kim Shepherd diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java new file mode 100644 index 0000000000..ba0bc2ad89 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java @@ -0,0 +1,357 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.external.provider.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.logging.log4j.Logger; +import org.dspace.app.sherpa.v2.SHERPAJournal; +import org.dspace.app.sherpa.v2.SHERPAResponse; +import org.dspace.content.dto.MetadataValueDTO; +import org.dspace.external.model.ExternalDataObject; +import org.dspace.external.provider.ExternalDataProvider; + +/** + * This class is the implementation of the ExternalDataProvider interface that will deal with SherpaJournal External + * data lookups. + * This provider is a refactored version of SherpaJournalDataPublisher, rewritten to work with SHERPA v2 API + * + * @author Kim Shepherd + */ +public class SHERPAv2JournalDataProvider implements ExternalDataProvider { + + private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(SHERPAv2JournalDataProvider.class); + + private String url; + private String sourceIdentifier; + private String apiKey; + + private CloseableHttpClient client = null; + + @Override + public String getSourceIdentifier() { + return sourceIdentifier; + } + + /** + * Initialise the client that we need to call the endpoint + * @throws IOException If something goes wrong + */ + public void init() throws IOException { + HttpClientBuilder builder = HttpClientBuilder.create(); + // httpclient 4.3+ doesn't appear to have any sensible defaults any more. Setting conservative defaults as + // not to hammer the SHERPA service too much. + client = builder + .disableAutomaticRetries() + .setMaxConnTotal(5) + .build(); + } + + /** + * Get a single journal based on a "title equals string" query + * @param id The journal title which will be used as query string + * @return external data object representing journal + */ + @Override + public Optional getExternalDataObject(String id) { + + HttpGet method = null; + SHERPAResponse sherpaResponse = null; + int timeout = 5000; + URIBuilder uriBuilder = null; + try { + // Construct URI for an exact match on journal title + uriBuilder = new URIBuilder(url); + uriBuilder.addParameter("item-type", "publication"); + uriBuilder.addParameter("filter", "[[\"title\",\"equals\",\"" + id + "\"]]"); + uriBuilder.addParameter("format", "Json"); + if (StringUtils.isNotBlank(apiKey)) { + uriBuilder.addParameter("api-key", apiKey); + } + + // Build HTTP method + method = new HttpGet(uriBuilder.build()); + method.setConfig(RequestConfig.custom() + .setConnectionRequestTimeout(timeout) + .setConnectTimeout(timeout) + .setSocketTimeout(timeout) + .build()); + + // Execute the method + HttpResponse response = client.execute(method); + int statusCode = response.getStatusLine().getStatusCode(); + + if (statusCode != HttpStatus.SC_OK) { + sherpaResponse = new SHERPAResponse("SHERPA/RoMEO return not OK status: " + + statusCode); + } + + HttpEntity responseBody = response.getEntity(); + + // Get InputStream from API response and parse JSON + if (null != responseBody) { + InputStream content = null; + try { + content = responseBody.getContent(); + sherpaResponse = new SHERPAResponse(content, SHERPAResponse.SHERPAFormat.JSON); + } catch (IOException e) { + log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e); + } finally { + if (content != null) { + content.close(); + } + } + } else { + sherpaResponse = new SHERPAResponse("SHERPA/RoMEO returned no response"); + } + } catch (Exception e) { + log.error("SHERPA/RoMEO query failed: ", e); + } + + if (sherpaResponse == null) { + sherpaResponse = new SHERPAResponse( + "Error processing the SHERPA/RoMEO answer"); + } + if (CollectionUtils.isNotEmpty(sherpaResponse.getJournals())) { + SHERPAJournal sherpaJournal = sherpaResponse.getJournals().get(0); + + ExternalDataObject externalDataObject = constructExternalDataObjectFromSherpaJournal(sherpaJournal); + return Optional.of(externalDataObject); + } + return null; + } + + /** + * Construct ExternalDataObject populated with journal metadata from the SHERPA v2 API response + * @param sherpaJournal + * @return external data object representing a journal + */ + private ExternalDataObject constructExternalDataObjectFromSherpaJournal(SHERPAJournal sherpaJournal) { + // Set up external object + ExternalDataObject externalDataObject = new ExternalDataObject(); + externalDataObject.setSource(sourceIdentifier); + // Set journal title in external object + if (CollectionUtils.isNotEmpty(sherpaJournal.getTitles())) { + String journalTitle = sherpaJournal.getTitles().get(0); + externalDataObject.setId(sherpaJournal.getTitles().get(0)); + externalDataObject.addMetadata(new MetadataValueDTO( + "dc", "title", null, null, journalTitle)); + externalDataObject.setValue(journalTitle); + externalDataObject.setDisplayValue(journalTitle); + } + // Set ISSNs in external object + if (CollectionUtils.isNotEmpty(sherpaJournal.getIssns())) { + String issn = sherpaJournal.getIssns().get(0); + externalDataObject.addMetadata(new MetadataValueDTO( + "dc", "identifier", "issn", null, issn)); + + } + + return externalDataObject; + } + + /** + * Search SHERPA v2 API for journal results based on a 'contains word' query + * @param query The query for the search + * @param start The start of the search + * @param limit The max amount of records to be returned by the search + * @return a list of external data objects + */ + @Override + public List searchExternalDataObjects(String query, int start, int limit) { + // query args to add to SHERPA/RoMEO request URL + HttpGet get = null; + try { + get = constructHttpGet(query, start, limit); + HttpClient hc = new DefaultHttpClient(); + HttpResponse response = hc.execute(get); + if (response.getStatusLine().getStatusCode() == 200) { + // Get response input stream and parse JSON into new SHERPAResponse object + InputStream content = null; + try { + content = response.getEntity().getContent(); + SHERPAResponse sherpaResponse = new SHERPAResponse(content, SHERPAResponse.SHERPAFormat.JSON); + if (CollectionUtils.isNotEmpty(sherpaResponse.getJournals())) { + List list = sherpaResponse.getJournals().stream().map( + sherpaJournal -> constructExternalDataObjectFromSherpaJournal(sherpaJournal)).collect( + Collectors.toList()); + + // Unlike the previous API version we can request offset and limit, so no need to build a + // sublist from this list, we can just return the list. + return list; + } + } catch (IOException e) { + log.error("Error parsing SHERPA response input stream: " + e.getMessage()); + } finally { + if (content != null) { + content.close(); + } + } + } + } catch (IOException | URISyntaxException e) { + log.error("SHERPA/RoMEO query failed: ", e); + return null; + } finally { + if (get != null) { + get.releaseConnection(); + } + } + return null; + } + + /** + * Construct HTTP GET object for a "title contains word" query using default start/limit parameters + * @param query a word or phrase to search for in journal title + * @return HttpGet method which can then be executed by the client + * @throws URISyntaxException if the URL build fails + */ + private HttpGet constructHttpGet(String query) throws URISyntaxException { + return constructHttpGet(query, -1, -1); + } + + /** + * Construct HTTP GET object for a "title contains word" query + * @param query the search query + * @param start row offset + * @param limit number of results to return + * @return HttpGet object to be executed by the client + * @throws URISyntaxException + */ + private HttpGet constructHttpGet(String query, int start, int limit) throws URISyntaxException { + // Build URL based on search query + URIBuilder uriBuilder = new URIBuilder(url); + uriBuilder.addParameter("item-type", "publication"); + uriBuilder.addParameter("filter", "[[\"title\",\"contains word\",\"" + query + "\"]]"); + uriBuilder.addParameter("format", "Json"); + // Set optional start (offset) and limit parameters + if (start >= 0) { + uriBuilder.addParameter("offset", String.valueOf(start)); + } + if (limit > 0) { + uriBuilder.addParameter("limit", String.valueOf(limit)); + } + if (StringUtils.isNotBlank(apiKey)) { + uriBuilder.addParameter("api-key", apiKey); + } + + // Create HTTP GET object + HttpGet method = new HttpGet(uriBuilder.build()); + + // Set connection parameters + int timeout = 5000; + method.setConfig(RequestConfig.custom() + .setConnectionRequestTimeout(timeout) + .setConnectTimeout(timeout) + .setSocketTimeout(timeout) + .build()); + return new HttpGet(uriBuilder.build()); + } + + @Override + public boolean supports(String source) { + return StringUtils.equalsIgnoreCase(sourceIdentifier, source); + } + + /** + * Get number of results returned from a SHERPA v2 publication search + * @param query The query to be search on and give the total amount of results + * @return int representing number of journal results + */ + @Override + public int getNumberOfResults(String query) { + HttpGet get = null; + try { + get = constructHttpGet(query); + HttpClient hc = new DefaultHttpClient(); + HttpResponse response = hc.execute(get); + if (response.getStatusLine().getStatusCode() == 200) { + // Read response and parse as SHERPAResponse object + InputStream content = null; + try { + content = response.getEntity().getContent(); + SHERPAResponse sherpaResponse = new SHERPAResponse(content, SHERPAResponse.SHERPAFormat.JSON); + if (CollectionUtils.isNotEmpty(sherpaResponse.getJournals())) { + return sherpaResponse.getJournals().size(); + } + } catch (IOException e) { + log.error("Error reading input stream for SHERPAResponse: " + e.getMessage()); + } finally { + if (content != null) { + content.close(); + } + } + } + } catch (IOException | URISyntaxException e) { + log.error("SHERPA/RoMEO query failed: ", e); + return 0; + } finally { + if (get != null) { + get.releaseConnection(); + } + } + // If other checks have failed return 0 + return 0; + } + + /** + * Generic setter for the sourceIdentifier + * @param sourceIdentifier The sourceIdentifier to be set on this SHERPAv2JournalDataProvider + */ + public void setSourceIdentifier(String sourceIdentifier) { + this.sourceIdentifier = sourceIdentifier; + } + + /** + * Generic getter for the url + * @return the url value of this SherpaJournalDataProvider + */ + public String getUrl() { + return url; + } + + /** + * Generic setter for the url + * @param url The url to be set on this SHERPAv2JournalDataProvider + */ + public void setUrl(String url) { + this.url = url; + } + + /** + * Generic getter for the apiKey + * @return the apiKey value of this SHERPAv2JournalDataProvider + */ + public String getApiKey() { + return apiKey; + } + + /** + * Generic setter for the apiKey + * @param apiKey The apiKey to be set on this SHERPAv2JournalDataProvider + */ + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } +} diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java new file mode 100644 index 0000000000..d24ca6d039 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java @@ -0,0 +1,360 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.external.provider.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.logging.log4j.Logger; +import org.dspace.app.sherpa.v2.SHERPAPublisher; +import org.dspace.app.sherpa.v2.SHERPAPublisherResponse; +import org.dspace.content.dto.MetadataValueDTO; +import org.dspace.external.model.ExternalDataObject; +import org.dspace.external.provider.ExternalDataProvider; + +/** + * This class is the implementation of the ExternalDataProvider interface that will deal with SHERPAPublisher External + * data lookups. + * This provider is a refactored version of SherpaPublisherDataPublisher, rewritten to work with SHERPA v2 API + * + * It uses a more simple response object than the normal publication / policy search + * + * @author Kim Shepherd + */ +public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { + + private static final Logger log = + org.apache.logging.log4j.LogManager.getLogger(SHERPAv2PublisherDataProvider.class); + + private String sourceIdentifier; + private String url; + private String apiKey; + + private CloseableHttpClient client = null; + + @Override + public String getSourceIdentifier() { + return sourceIdentifier; + } + + /** + * Initialise the client that we need to call the endpoint + * @throws IOException If something goes wrong + */ + public void init() throws IOException { + HttpClientBuilder builder = HttpClientBuilder.create(); + // httpclient 4.3+ doesn't appear to have any sensible defaults any more. Setting conservative defaults as + // not to hammer the SHERPA service too much. + client = builder + .disableAutomaticRetries() + .setMaxConnTotal(5) + .build(); + } + + /** + * Get a single publisher based on a "id equals string" query + * @param id The publisher ID which will be used as query string + * @return external data object representing publisher + */ + @Override + public Optional getExternalDataObject(String id) { + + HttpGet method = null; + SHERPAPublisherResponse sherpaResponse = null; + int timeout = 5000; + URIBuilder uriBuilder = null; + try { + // Construct URI for an exact match on journal title + uriBuilder = new URIBuilder(url); + uriBuilder.addParameter("item-type", "publisher"); + uriBuilder.addParameter("filter", "[[\"id\",\"equals\",\"" + id + "\"]]"); + uriBuilder.addParameter("format", "Json"); + if (StringUtils.isNotBlank(apiKey)) { + uriBuilder.addParameter("api-key", apiKey); + } + + // Build HTTP method + method = new HttpGet(uriBuilder.build()); + method.setConfig(RequestConfig.custom() + .setConnectionRequestTimeout(timeout) + .setConnectTimeout(timeout) + .setSocketTimeout(timeout) + .build()); + + // Execute the method + HttpResponse response = client.execute(method); + int statusCode = response.getStatusLine().getStatusCode(); + + if (statusCode != HttpStatus.SC_OK) { + sherpaResponse = new SHERPAPublisherResponse("SHERPA/RoMEO return not OK status: " + + statusCode); + } + + HttpEntity responseBody = response.getEntity(); + + // Get InputStream from API response and parse JSON + if (null != responseBody) { + InputStream content = null; + try { + content = responseBody.getContent(); + sherpaResponse = new SHERPAPublisherResponse(content, SHERPAPublisherResponse.SHERPAFormat.JSON); + } catch (IOException e) { + log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e); + } finally { + if (content != null) { + content.close(); + } + } + } else { + sherpaResponse = new SHERPAPublisherResponse("SHERPA/RoMEO returned no response"); + } + } catch (Exception e) { + log.error("SHERPA/RoMEO query failed: ", e); + } + + if (sherpaResponse == null) { + sherpaResponse = new SHERPAPublisherResponse("Error processing the SHERPA/RoMEO answer"); + } + if (CollectionUtils.isNotEmpty(sherpaResponse.getPublishers())) { + SHERPAPublisher sherpaPublisher = sherpaResponse.getPublishers().get(0); + // Construct external data object from returned publisher + ExternalDataObject externalDataObject = constructExternalDataObjectFromSherpaPublisher(sherpaPublisher); + return Optional.of(externalDataObject); + } + return null; + } + + /** + * Search SHERPA v2 API for publisher results based on a 'contains word' query for publisher name + * @param query The query for the search + * @param start The start of the search + * @param limit The max amount of records to be returned by the search + * @return a list of external data objects + */ + @Override + public List searchExternalDataObjects(String query, int start, int limit) { + // query args to add to SHERPA/RoMEO request URL + HttpGet get = null; + try { + get = constructHttpGet(query, start, limit); + HttpClient hc = new DefaultHttpClient(); + HttpResponse response = hc.execute(get); + if (response.getStatusLine().getStatusCode() == 200) { + // Get response input stream and parse JSON into new SHERPAResponse object + InputStream content = null; + try { + content = response.getEntity().getContent(); + SHERPAPublisherResponse sherpaResponse = + new SHERPAPublisherResponse(content, SHERPAPublisherResponse.SHERPAFormat.JSON); + if (CollectionUtils.isNotEmpty(sherpaResponse.getPublishers())) { + List list = sherpaResponse.getPublishers().stream().map( + sherpaPublisher -> constructExternalDataObjectFromSherpaPublisher(sherpaPublisher)).collect( + Collectors.toList()); + + // Unlike the previous API version we can request offset and limit, so no need to build a + // sublist from this list, we can just return the list. + return list; + } + } catch (IOException e) { + log.error("Error parsing SHERPA response input stream: " + e.getMessage()); + } finally { + if (content != null) { + content.close(); + } + } + } + } catch (IOException | URISyntaxException e) { + log.error("SHERPA/RoMEO query failed: ", e); + return null; + } finally { + if (get != null) { + get.releaseConnection(); + } + } + return null; + } + + /** + * Construct HTTP GET object for a "publisher name contains word" query using default start/limit parameters + * @param query a word or phrase to search for in publisher name + * @return HttpGet method which can then be executed by the client + * @throws URISyntaxException if the URL build fails + */ + private HttpGet constructHttpGet(String query) throws URISyntaxException { + return constructHttpGet(query, -1, -1); + } + + /** + * Construct HTTP GET object for a "publisher name contains word" query + * @param query the search query + * @param start row offset + * @param limit number of results to return + * @return HttpGet object to be executed by the client + * @throws URISyntaxException + */ + private HttpGet constructHttpGet(String query, int start, int limit) throws URISyntaxException { + // Build URL based on search query + URIBuilder uriBuilder = new URIBuilder(url); + uriBuilder.addParameter("item-type", "publisher"); + uriBuilder.addParameter("filter", "[[\"name\",\"contains word\",\"" + query + "\"]]"); + uriBuilder.addParameter("format", "Json"); + // Set optional start (offset) and limit parameters + if (start >= 0) { + uriBuilder.addParameter("offset", String.valueOf(start)); + } + if (limit > 0) { + uriBuilder.addParameter("limit", String.valueOf(limit)); + } + if (StringUtils.isNotBlank(apiKey)) { + uriBuilder.addParameter("api-key", apiKey); + } + + // Create HTTP GET object + HttpGet method = new HttpGet(uriBuilder.build()); + + // Set connection parameters + int timeout = 5000; + method.setConfig(RequestConfig.custom() + .setConnectionRequestTimeout(timeout) + .setConnectTimeout(timeout) + .setSocketTimeout(timeout) + .build()); + return new HttpGet(uriBuilder.build()); + } + + private ExternalDataObject constructExternalDataObjectFromSherpaPublisher(SHERPAPublisher sherpaPublisher) { + ExternalDataObject externalDataObject = new ExternalDataObject(); + externalDataObject.setSource(sourceIdentifier); + + // Set publisher name + if (StringUtils.isNotBlank(sherpaPublisher.getName())) { + externalDataObject.addMetadata(new MetadataValueDTO( + "dc", "title", null, null, sherpaPublisher.getName())); + externalDataObject.setDisplayValue(sherpaPublisher.getName()); + externalDataObject.setValue(sherpaPublisher.getName()); + } + // Set publisher ID + if (StringUtils.isNotBlank(sherpaPublisher.getIdentifier())) { + externalDataObject.setId(sherpaPublisher.getIdentifier()); + externalDataObject.addMetadata(new MetadataValueDTO( + "dc", "identifier", "sherpaPublisher", null, + sherpaPublisher.getIdentifier())); + } + + // Set home URL + if (StringUtils.isNotBlank(sherpaPublisher.getUri())) { + externalDataObject.addMetadata(new MetadataValueDTO( + "dc", "identifier", "other", null, sherpaPublisher.getUri())); + } + + return externalDataObject; + } + + @Override + public boolean supports(String source) { + return StringUtils.equalsIgnoreCase(sourceIdentifier, source); + } + + /** + * Get number of results returned from a SHERPA v2 publication search + * @param query The query to be search on and give the total amount of results + * @return int representing number of publisher results + */ + @Override + public int getNumberOfResults(String query) { + HttpGet get = null; + try { + get = constructHttpGet(query); + HttpClient hc = new DefaultHttpClient(); + HttpResponse response = hc.execute(get); + if (response.getStatusLine().getStatusCode() == 200) { + // Read response and parse as SHERPAResponse object + InputStream content = null; + try { + content = response.getEntity().getContent(); + SHERPAPublisherResponse sherpaResponse = + new SHERPAPublisherResponse(content, SHERPAPublisherResponse.SHERPAFormat.JSON); + if (CollectionUtils.isNotEmpty(sherpaResponse.getPublishers())) { + return sherpaResponse.getPublishers().size(); + } + } catch (IOException e) { + log.error("Error reading input stream for SHERPAResponse: " + e.getMessage()); + } finally { + if (content != null) { + content.close(); + } + } + } + } catch (IOException | URISyntaxException e) { + log.error("SHERPA/RoMEO query failed: ", e); + return 0; + } finally { + if (get != null) { + get.releaseConnection(); + } + } + // If other checks have failed return 0 + return 0; + } + + /** + * Generic setter for the sourceIdentifier + * @param sourceIdentifier The sourceIdentifier to be set on this SHERPAv2PublisherDataProvider + */ + public void setSourceIdentifier(String sourceIdentifier) { + this.sourceIdentifier = sourceIdentifier; + } + + /** + * Generic getter for the url + * @return the url value of this SHERPAv2PublisherDataProvider + */ + public String getUrl() { + return url; + } + + /** + * Generic setter for the url + * @param url The url to be set on this SHERPAv2PublisherDataProvider + */ + public void setUrl(String url) { + this.url = url; + } + + /** + * Generic getter for the apiKey + * @return the apiKey value of this SHERPAv2PublisherDataProvider + */ + public String getApiKey() { + return apiKey; + } + + /** + * Generic setter for the apiKey + * @param apiKey The apiKey to be set on this SHERPAv2PublisherDataProvider + */ + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } +} From 6abb1d96f7699dbff1d55834cafae4be69393cf7 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Tue, 5 May 2020 14:27:09 +1200 Subject: [PATCH 031/179] [DS-3940](master) Unit tests for SHERPAResponse, SHERPAPublisherResponse --- .../v2/SHERPAPublisherResponseTest.java | 88 +++ .../app/sherpa/v2/SHERPAResponseTest.java | 98 +++ .../org/dspace/app/sherpa/v2/plos.json | 619 +++++++++++++++++ .../org/dspace/app/sherpa/v2/thelancet.json | 652 ++++++++++++++++++ 4 files changed, 1457 insertions(+) create mode 100644 dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java create mode 100644 dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java create mode 100644 dspace-api/src/test/resources/org/dspace/app/sherpa/v2/plos.json create mode 100644 dspace-api/src/test/resources/org/dspace/app/sherpa/v2/thelancet.json diff --git a/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java b/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java new file mode 100644 index 0000000000..57715e83d4 --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java @@ -0,0 +1,88 @@ +package org.dspace.app.sherpa.v2; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.InputStream; + + +import org.apache.commons.collections4.CollectionUtils; +import org.dspace.AbstractDSpaceTest; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class SHERPAPublisherResponseTest extends AbstractDSpaceTest { + + public SHERPAPublisherResponseTest() { + + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + /** + * Test that the SHERPA API response (in this case saved as local JSON) is correctly + * parsed and resulting objects have expected values + * @throws IOException + */ + @Test + public void testParseJSON() throws IOException { + + InputStream content = null; + try { + // Get mock JSON - in this case, a known good result for PLOS + content = getClass().getResourceAsStream("plos.json"); + + // Parse JSON input stream + SHERPAPublisherResponse response = new SHERPAPublisherResponse(content, + SHERPAPublisherResponse.SHERPAFormat.JSON); + + // Assert response is not error, or fail with message + assertFalse("Response was flagged as 'isError'", response.isError()); + + // Assert response has at least one publisher result, or fail with message + assertTrue("List of publishers did not contain at least one parsed publisher", + CollectionUtils.isNotEmpty(response.getPublishers())); + + // Assert response has a publisher with name "Public Library of Science", or fail with message + String expectedName = "Public Library of Science"; + assertEquals("Publisher name did not match expected '" + expectedName + "' value", + expectedName, response.getPublishers().get(0).getName()); + + // Assert response has expected publisher URL + String expectedUrl = "http://www.plos.org/"; + assertEquals("Response metadata URI did not match expected '" + expectedUrl + + "' value", expectedUrl, response.getPublishers().get(0).getUri()); + + // Assert response has at expected publisher ID + String expectedId = "112"; + assertEquals("Response publisher ID did not match expected ID " + expectedId, + expectedId, response.getPublishers().get(0).getIdentifier()); + + } catch(IOException e) { + throw new RuntimeException(e.getMessage(), e); + } finally { + if (content != null) { + content.close(); + } + } + } +} diff --git a/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java b/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java new file mode 100644 index 0000000000..285f0c67ed --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java @@ -0,0 +1,98 @@ +package org.dspace.app.sherpa.v2; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.collections4.CollectionUtils; +import org.dspace.AbstractDSpaceTest; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class SHERPAResponseTest extends AbstractDSpaceTest { + + public SHERPAResponseTest() { + + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + /** + * Test that the SHERPA API response (in this case saved as local JSON) is correctly + * parsed and resulting objects have expected values + * @throws IOException + */ + @Test + public void testParseJSON() throws IOException { + + InputStream content = null; + try { + // Get mock JSON - in this case, a known good result for The Lancet + content = getClass().getResourceAsStream("thelancet.json"); + + // Parse JSON input stream + SHERPAResponse response = new SHERPAResponse(content, SHERPAResponse.SHERPAFormat.JSON); + + // Assert response is not error, or fail with message + assertFalse("Response was flagged as 'isError'", response.isError()); + + // Assert response has at least one journal result, or fail with message + assertTrue("List of journals did not contain at least one parsed journal", + CollectionUtils.isNotEmpty(response.getJournals())); + + // Assert response has a journal with title "The Lancet", or fail with message + String expectedTitle = "The Lancet"; + assertTrue("Journal title did not match expected '" + expectedTitle + "' value", + CollectionUtils.isNotEmpty(response.getJournals().get(0).getTitles()) + && expectedTitle.equals(response.getJournals().get(0).getTitles().get(0))); + + // Assert response has expected publication (metadata) URI + String expectedSystemMetadataUri = "http://v2.sherpa.ac.uk/id/publication/23803"; + assertTrue("Response metadata URI did not match expected '" + expectedSystemMetadataUri + + "' value", expectedSystemMetadataUri.equals(response.getMetadata().getUri())); + + // Assert response has at least one policy + assertTrue("Response did not contain at least one archiving policy", + CollectionUtils.isNotEmpty(response.getJournals().get(0).getPolicies())); + + // Assert response has at least one permitted version + assertTrue("Response did not contain at least one permitted version", + CollectionUtils.isNotEmpty(response.getJournals().get(0).getPolicies().get(0).getPermittedVersions())); + + // Assert journal has at least one publisher + assertTrue("Response did not contain at least one publisher", + CollectionUtils.isNotEmpty(response.getJournals().get(0).getPublishers())); + + // Assert first publisher has name 'Elsevier' + String expectedPublisherName = "Elsevier"; + assertTrue("Response did not contain expected publisher name '" + expectedPublisherName + "'", + expectedPublisherName.equals(response.getJournals().get(0).getPublisher().getName())); + } catch(IOException e) { + throw new RuntimeException(e.getMessage(), e); + } finally { + if (content != null) { + content.close(); + } + } + } +} diff --git a/dspace-api/src/test/resources/org/dspace/app/sherpa/v2/plos.json b/dspace-api/src/test/resources/org/dspace/app/sherpa/v2/plos.json new file mode 100644 index 0000000000..d5c85fe5b7 --- /dev/null +++ b/dspace-api/src/test/resources/org/dspace/app/sherpa/v2/plos.json @@ -0,0 +1,619 @@ +{ + "items" : [ + { + "country" : "us", + "name" : [ + { + "preferred" : "name", + "name" : "Public Library of Science", + "preferred_phrases" : [ + { + "language" : "en", + "phrase" : "Name", + "value" : "name" + } + ], + "language" : "en", + "language_phrases" : [ + { + "value" : "en", + "phrase" : "English", + "language" : "en" + } + ] + } + ], + "country_phrases" : [ + { + "language" : "en", + "phrase" : "United States of America", + "value" : "us" + } + ], + "id" : 112, + "url" : "http://www.plos.org/", + "publication_count" : 7, + "system_metadata" : { + "id" : 112, + "publicly_visible" : "yes", + "uri" : "http://v2.sherpa.ac.uk/id/publisher/112", + "date_created" : "2005-02-07 00:00:00", + "publicly_visible_phrases" : [ + { + "value" : "yes", + "phrase" : "Yes", + "language" : "en" + } + ], + "date_modified" : "2019-05-20 11:49:24" + }, + "publications" : [ + { + "title" : [ + { + "title" : "PLoS Biology", + "language" : "en", + "language_phrases" : [ + { + "value" : "en", + "language" : "en", + "phrase" : "English" + } + ] + } + ], + "uri" : "http://v2.sherpa.ac.uk/id/publication/17601", + "id" : 17601, + "type" : "journal", + "issns" : [ + { + "type_phrases" : [ + { + "language" : "en", + "phrase" : "Print", + "value" : "print" + } + ], + "issn" : "1544-9173", + "type" : "print" + }, + { + "type" : "electronic", + "type_phrases" : [ + { + "language" : "en", + "phrase" : "Electronic", + "value" : "electronic" + } + ], + "issn" : "1545-7885" + } + ], + "type_phrases" : [ + { + "value" : "journal", + "language" : "en", + "phrase" : "Journal" + } + ] + }, + { + "title" : [ + { + "title" : "PLoS Computational Biology", + "language" : "en", + "language_phrases" : [ + { + "value" : "en", + "language" : "en", + "phrase" : "English" + } + ] + } + ], + "id" : 17595, + "uri" : "http://v2.sherpa.ac.uk/id/publication/17595", + "type" : "journal", + "issns" : [ + { + "type_phrases" : [ + { + "language" : "en", + "phrase" : "Print", + "value" : "print" + } + ], + "issn" : "1553-734X", + "type" : "print" + }, + { + "type" : "electronic", + "type_phrases" : [ + { + "language" : "en", + "phrase" : "Electronic", + "value" : "electronic" + } + ], + "issn" : "1553-7358" + } + ], + "type_phrases" : [ + { + "value" : "journal", + "phrase" : "Journal", + "language" : "en" + } + ] + }, + { + "type_phrases" : [ + { + "value" : "journal", + "language" : "en", + "phrase" : "Journal" + } + ], + "issns" : [ + { + "type_phrases" : [ + { + "language" : "en", + "phrase" : "Print", + "value" : "print" + } + ], + "issn" : "1553-7390", + "type" : "print" + }, + { + "issn" : "1553-7404", + "type_phrases" : [ + { + "language" : "en", + "phrase" : "Electronic", + "value" : "electronic" + } + ], + "type" : "electronic" + } + ], + "title" : [ + { + "title" : "PLoS Genetics", + "language_phrases" : [ + { + "value" : "en", + "language" : "en", + "phrase" : "English" + } + ], + "language" : "en" + } + ], + "id" : 17596, + "uri" : "http://v2.sherpa.ac.uk/id/publication/17596", + "type" : "journal" + }, + { + "uri" : "http://v2.sherpa.ac.uk/id/publication/17597", + "id" : 17597, + "title" : [ + { + "language_phrases" : [ + { + "phrase" : "English", + "language" : "en", + "value" : "en" + } + ], + "language" : "en", + "title" : "PLoS Medicine" + } + ], + "type" : "journal", + "issns" : [ + { + "type_phrases" : [ + { + "value" : "print", + "phrase" : "Print", + "language" : "en" + } + ], + "issn" : "1549-1277", + "type" : "print" + }, + { + "type" : "electronic", + "issn" : "1549-1676", + "type_phrases" : [ + { + "language" : "en", + "phrase" : "Electronic", + "value" : "electronic" + } + ] + } + ], + "type_phrases" : [ + { + "value" : "journal", + "language" : "en", + "phrase" : "Journal" + } + ] + }, + { + "title" : [ + { + "language_phrases" : [ + { + "value" : "en", + "language" : "en", + "phrase" : "English" + } + ], + "language" : "en", + "acronym" : "PLoS NTDs", + "title" : "PLoS Neglected Tropical Diseases" + } + ], + "id" : 17598, + "uri" : "http://v2.sherpa.ac.uk/id/publication/17598", + "type" : "journal", + "issns" : [ + { + "type" : "electronic", + "type_phrases" : [ + { + "language" : "en", + "phrase" : "Electronic", + "value" : "electronic" + } + ], + "issn" : "1935-2735" + } + ], + "type_phrases" : [ + { + "value" : "journal", + "language" : "en", + "phrase" : "Journal" + } + ] + }, + { + "issns" : [ + { + "type" : "electronic", + "type_phrases" : [ + { + "value" : "electronic", + "language" : "en", + "phrase" : "Electronic" + } + ], + "issn" : "1932-6203" + } + ], + "type_phrases" : [ + { + "value" : "journal", + "language" : "en", + "phrase" : "Journal" + } + ], + "uri" : "http://v2.sherpa.ac.uk/id/publication/17599", + "id" : 17599, + "title" : [ + { + "language" : "en", + "language_phrases" : [ + { + "language" : "en", + "phrase" : "English", + "value" : "en" + } + ], + "title" : "PLoS ONE" + } + ], + "type" : "journal" + }, + { + "issns" : [ + { + "type" : "print", + "issn" : "1553-7366", + "type_phrases" : [ + { + "language" : "en", + "phrase" : "Print", + "value" : "print" + } + ] + }, + { + "type" : "electronic", + "issn" : "1553-7374", + "type_phrases" : [ + { + "phrase" : "Electronic", + "language" : "en", + "value" : "electronic" + } + ] + } + ], + "type_phrases" : [ + { + "value" : "journal", + "phrase" : "Journal", + "language" : "en" + } + ], + "id" : 17600, + "title" : [ + { + "title" : "PLoS Pathogens", + "language_phrases" : [ + { + "value" : "en", + "phrase" : "English", + "language" : "en" + } + ], + "language" : "en" + } + ], + "uri" : "http://v2.sherpa.ac.uk/id/publication/17600", + "type" : "journal" + } + ], + "policies" : [ + { + "open_access_prohibited_phrases" : [ + { + "phrase" : "No", + "language" : "en", + "value" : "no" + } + ], + "internal_moniker" : "Default policy", + "id" : 112, + "uri" : "http://v2.sherpa.ac.uk/id/publisher_policy/112", + "open_access_prohibited" : "no", + "permitted_oa" : [ + { + "license" : [ + { + "license" : "cc_by", + "license_phrases" : [ + { + "value" : "cc_by", + "phrase" : "CC BY", + "language" : "en" + } + ], + "version" : "4" + } + ], + "copyright_owner_phrases" : [ + { + "phrase" : "Authors", + "language" : "en", + "value" : "authors" + } + ], + "location" : { + "location" : [ + "preprint_repository" + ], + "location_phrases" : [ + { + "value" : "preprint_repository", + "language" : "en", + "phrase" : "Preprint Repository" + } + ] + }, + "copyright_owner" : "authors", + "article_version" : [ + "submitted" + ], + "additional_oa_fee_phrases" : [ + { + "phrase" : "No", + "language" : "en", + "value" : "no" + } + ], + "conditions" : [ + "Published source must be acknowledged with citation" + ], + "article_version_phrases" : [ + { + "phrase" : "Submitted", + "language" : "en", + "value" : "submitted" + } + ], + "additional_oa_fee" : "no" + }, + { + "additional_oa_fee" : "no", + "article_version_phrases" : [ + { + "value" : "accepted", + "phrase" : "Accepted", + "language" : "en" + } + ], + "location" : { + "location_phrases" : [ + { + "phrase" : "Any Website", + "language" : "en", + "value" : "any_website" + } + ], + "location" : [ + "any_website" + ] + }, + "license" : [ + { + "license" : "cc_by", + "license_phrases" : [ + { + "language" : "en", + "phrase" : "CC BY", + "value" : "cc_by" + } + ], + "version" : "4" + } + ], + "copyright_owner_phrases" : [ + { + "phrase" : "Authors", + "language" : "en", + "value" : "authors" + } + ], + "additional_oa_fee_phrases" : [ + { + "phrase" : "No", + "language" : "en", + "value" : "no" + } + ], + "copyright_owner" : "authors", + "article_version" : [ + "accepted" + ] + }, + { + "additional_oa_fee" : "no", + "article_version_phrases" : [ + { + "language" : "en", + "phrase" : "Published", + "value" : "published" + } + ], + "publisher_deposit" : [ + { + "repository_metadata" : { + "type_phrases" : [ + { + "value" : "disciplinary", + "phrase" : "Disciplinary", + "language" : "en" + } + ], + "description" : "A subject-based repository of biomedical and life sciences journal literature developed and managed by the National Center for Biotechnology Information (NCBI) at the US National Library of Medicine (NLM). \r\n\r\nContent includes articles deposited by participating journals that have applied to and been selected for the archive by NLM, as well as individual author manuscripts that have been submitted in compliance with the NIH Public Access Policy and similar policies of other research funding agencies. More than 2000 journals currently use PMC as a repository. Digitization projects have also added content from the 18th, 19th, and 20th centuries to the archive.", + "url" : "http://www.ncbi.nlm.nih.gov/pmc/", + "name" : [ + { + "preferred" : "name", + "name" : "PubMed Central", + "preferred_phrases" : [ + { + "language" : "en", + "phrase" : "Name", + "value" : "name" + } + ], + "language" : "en", + "language_phrases" : [ + { + "phrase" : "English", + "language" : "en", + "value" : "en" + } + ] + } + ], + "type" : "disciplinary" + }, + "system_metadata" : { + "id" : 267, + "uri" : "http://v2.sherpa.ac.uk/id/repository/267" + } + } + ], + "conditions" : [ + "Published source must be acknowledged with citation" + ], + "copyright_owner" : "authors", + "article_version" : [ + "published" + ], + "additional_oa_fee_phrases" : [ + { + "value" : "no", + "phrase" : "No", + "language" : "en" + } + ], + "license" : [ + { + "license" : "cc_by", + "license_phrases" : [ + { + "language" : "en", + "phrase" : "CC BY", + "value" : "cc_by" + } + ], + "version" : "4.0" + } + ], + "copyright_owner_phrases" : [ + { + "value" : "authors", + "phrase" : "Authors", + "language" : "en" + } + ], + "location" : { + "named_repository" : [ + "PubMed Central" + ], + "location_phrases" : [ + { + "language" : "en", + "phrase" : "Named Repository", + "value" : "named_repository" + }, + { + "value" : "this_journal", + "language" : "en", + "phrase" : "This Journal" + } + ], + "location" : [ + "named_repository", + "this_journal" + ] + } + } + ], + "urls" : [ + { + "description" : "Pre-print Server policy", + "url" : "http://journals.plos.org/plosone/s/ethical-publishing-practice#loc-preprint-servers" + }, + { + "description" : "Open Access", + "url" : "https://www.plos.org/open-access/" + } + ], + "publication_count" : 7 + } + ] + } + ] +} \ No newline at end of file diff --git a/dspace-api/src/test/resources/org/dspace/app/sherpa/v2/thelancet.json b/dspace-api/src/test/resources/org/dspace/app/sherpa/v2/thelancet.json new file mode 100644 index 0000000000..6ff3440a44 --- /dev/null +++ b/dspace-api/src/test/resources/org/dspace/app/sherpa/v2/thelancet.json @@ -0,0 +1,652 @@ +{ + "items" : [ + { + "url" : "http://www.thelancet.com/journals/lancet/issue/current", + "issns" : [ + { + "issn" : "0140-6736", + "type_phrases" : [ + { + "phrase" : "Print", + "language" : "en", + "value" : "print" + } + ], + "type" : "print" + }, + { + "issn" : "1474-547X", + "type_phrases" : [ + { + "language" : "en", + "phrase" : "Electronic", + "value" : "electronic" + } + ], + "type" : "electronic" + } + ], + "id" : 23803, + "publishers" : [ + { + "relationship_type_phrases" : [ + { + "value" : "commercial_publisher", + "language" : "en", + "phrase" : "Commercial Publisher" + } + ], + "publisher" : { + "imprints_id" : [ + 7920, + 131, + 26532, + 31689, + 22233, + 265, + 28437, + 34765, + 29029, + 23104, + 5264, + 36376, + 985 + ], + "country_phrases" : [ + { + "value" : "us", + "phrase" : "United States of America", + "language" : "en" + } + ], + "uri" : "http://v2.sherpa.ac.uk/id/publisher/30", + "id" : 30, + "name" : [ + { + "language" : "en", + "language_phrases" : [ + { + "value" : "en", + "language" : "en", + "phrase" : "English" + } + ], + "preferred" : "name", + "preferred_phrases" : [ + { + "language" : "en", + "phrase" : "Name", + "value" : "name" + } + ], + "name" : "Elsevier" + } + ], + "country" : "us", + "publication_count" : 2801, + "url" : "http://www.elsevier.com/" + }, + "relationship_type" : "commercial_publisher" + } + ], + "listed_in_doaj" : "no", + "system_metadata" : { + "id" : 23803, + "publicly_visible_phrases" : [ + { + "phrase" : "Yes", + "language" : "en", + "value" : "yes" + } + ], + "uri" : "http://v2.sherpa.ac.uk/id/publication/23803", + "date_modified" : "2020-03-06 11:25:54", + "date_created" : "2012-11-20 14:51:52", + "publicly_visible" : "yes" + }, + "type_phrases" : [ + { + "language" : "en", + "phrase" : "Journal", + "value" : "journal" + } + ], + "publisher_policy" : [ + { + "publication_count" : 12, + "id" : 1274, + "permitted_oa" : [ + { + "additional_oa_fee_phrases" : [ + { + "language" : "en", + "phrase" : "No", + "value" : "no" + } + ], + "article_version" : [ + "submitted" + ], + "conditions" : [ + "Upon publication publisher copyright and source must be acknowledged", + "Upon publication must link to publisher version" + ], + "article_version_phrases" : [ + { + "value" : "submitted", + "language" : "en", + "phrase" : "Submitted" + } + ], + "location" : { + "location_phrases" : [ + { + "value" : "authors_homepage", + "language" : "en", + "phrase" : "Author's Homepage" + }, + { + "value" : "preprint_repository", + "phrase" : "Preprint Repository", + "language" : "en" + } + ], + "location" : [ + "authors_homepage", + "preprint_repository" + ] + }, + "additional_oa_fee" : "no" + }, + { + "additional_oa_fee_phrases" : [ + { + "language" : "en", + "phrase" : "No", + "value" : "no" + } + ], + "article_version" : [ + "accepted" + ], + "conditions" : [ + "Publisher copyright and source must be acknowledged", + "Must link to publisher version" + ], + "article_version_phrases" : [ + { + "phrase" : "Accepted", + "language" : "en", + "value" : "accepted" + } + ], + "license" : [ + { + "license_phrases" : [ + { + "language" : "en", + "phrase" : "CC BY-NC-ND", + "value" : "cc_by_nc_nd" + } + ], + "license" : "cc_by_nc_nd" + } + ], + "location" : { + "location" : [ + "authors_homepage", + "institutional_website" + ], + "location_phrases" : [ + { + "value" : "authors_homepage", + "phrase" : "Author's Homepage", + "language" : "en" + }, + { + "value" : "institutional_website", + "language" : "en", + "phrase" : "Institutional Website" + } + ] + }, + "additional_oa_fee" : "no" + }, + { + "article_version" : [ + "accepted" + ], + "embargo" : { + "amount" : 6, + "units_phrases" : [ + { + "value" : "months", + "phrase" : "Months", + "language" : "en" + } + ], + "units" : "months" + }, + "location" : { + "location_phrases" : [ + { + "value" : "non_commercial_repository", + "phrase" : "Non-Commercial Repository", + "language" : "en" + } + ], + "location" : [ + "non_commercial_repository" + ] + }, + "article_version_phrases" : [ + { + "phrase" : "Accepted", + "language" : "en", + "value" : "accepted" + } + ], + "conditions" : [ + "Publisher copyright and source must be acknowledged", + "Must link to publisher version" + ], + "additional_oa_fee_phrases" : [ + { + "phrase" : "No", + "language" : "en", + "value" : "no" + } + ], + "prerequisites" : { + "prerequisites" : [ + "when_required_by_funder" + ], + "prerequisites_phrases" : [ + { + "value" : "when_required_by_funder", + "phrase" : "If Required by Funder", + "language" : "en" + } + ] + }, + "additional_oa_fee" : "no", + "license" : [ + { + "license" : "cc_by_nc_nd", + "license_phrases" : [ + { + "value" : "cc_by_nc_nd", + "language" : "en", + "phrase" : "CC BY-NC-ND" + } + ] + } + ] + }, + { + "additional_oa_fee" : "no", + "additional_oa_fee_phrases" : [ + { + "language" : "en", + "phrase" : "No", + "value" : "no" + } + ], + "prerequisites" : { + "prerequisite_funders" : [ + { + "funder_metadata" : { + "id" : 9, + "identifiers" : [ + { + "type_phrases" : [ + { + "value" : "fundref", + "phrase" : "FundRef DOI", + "language" : "en" + } + ], + "type" : "fundref", + "identifier" : "http://dx.doi.org/10.13039/100000002" + } + ], + "name" : [ + { + "preferred" : "name", + "preferred_phrases" : [ + { + "value" : "name", + "language" : "en", + "phrase" : "Name" + } + ], + "name" : "National Institutes of Health", + "language" : "en", + "language_phrases" : [ + { + "phrase" : "English", + "language" : "en", + "value" : "en" + } + ], + "acronym" : "NIH" + } + ], + "country" : "us", + "country_phrases" : [ + { + "value" : "us", + "phrase" : "United States of America", + "language" : "en" + } + ], + "url" : [ + { + "language" : "en", + "language_phrases" : [ + { + "value" : "en", + "phrase" : "English", + "language" : "en" + } + ], + "url" : "http://www.nih.gov/" + } + ] + }, + "system_metadata" : { + "id" : 9, + "uri" : "http://v2.sherpa.ac.uk/id/funder/9" + } + } + ] + }, + "article_version_phrases" : [ + { + "phrase" : "Accepted", + "language" : "en", + "value" : "accepted" + } + ], + "conditions" : [ + "Publisher copyright and source must be acknowledged", + "Must link to publisher version" + ], + "location" : { + "location_phrases" : [ + { + "value" : "non_commercial_repository", + "phrase" : "Non-Commercial Repository", + "language" : "en" + } + ], + "location" : [ + "non_commercial_repository" + ] + }, + "embargo" : { + "units" : "months", + "units_phrases" : [ + { + "value" : "months", + "language" : "en", + "phrase" : "Months" + } + ], + "amount" : 12 + }, + "article_version" : [ + "accepted" + ] + } + ], + "uri" : "http://v2.sherpa.ac.uk/id/publisher_policy/1274", + "urls" : [ + { + "description" : "Guidelines for Authors", + "url" : "http://download.thelancet.com/flatcontentassets/authors/lancet-information-for-authors.pdf" + }, + { + "description" : "Disclosure of results before publication", + "url" : "http://www.thelancet.com/lancet/information-for-authors/disclosure-of-results" + }, + { + "description" : "The Lancet journals welcome a new open access policy", + "url" : "http://www.thelancet.com/journals/lancet/article/PIIS0140-6736%2813%2960720-5/fulltext" + }, + { + "url" : "http://www.thelancet.com/lancet-information-for-authors/after-publication", + "description" : "What happens after publication?" + }, + { + "url" : "https://www.elsevier.com/__data/assets/pdf_file/0005/78476/external-embargo-list.pdf", + "description" : "Journal Embargo Period List" + }, + { + "description" : "Journal Embargo List for UK Authors", + "url" : "https://www.elsevier.com/__data/assets/pdf_file/0011/78473/UK-Embargo-Periods.pdf" + } + ], + "open_access_prohibited_phrases" : [ + { + "value" : "no", + "phrase" : "No", + "language" : "en" + } + ], + "internal_moniker" : "Lancet", + "open_access_prohibited" : "no" + }, + { + "open_access_prohibited_phrases" : [ + { + "value" : "no", + "language" : "en", + "phrase" : "No" + } + ], + "internal_moniker" : "Open access option", + "open_access_prohibited" : "no", + "permitted_oa" : [ + { + "additional_oa_fee_phrases" : [ + { + "value" : "yes", + "language" : "en", + "phrase" : "Yes" + } + ], + "article_version" : [ + "published" + ], + "conditions" : [ + "Published source must be acknowledged with citation" + ], + "article_version_phrases" : [ + { + "value" : "published", + "language" : "en", + "phrase" : "Published" + } + ], + "license" : [ + { + "license" : "cc_by_nc_nd", + "license_phrases" : [ + { + "value" : "cc_by_nc_nd", + "phrase" : "CC BY-NC-ND", + "language" : "en" + } + ], + "version" : "4.0" + } + ], + "location" : { + "named_repository" : [ + "PubMed Central", + "Research for Development Repository", + "ESRC Research Catalogue" + ], + "location" : [ + "named_repository", + "non_commercial_repository", + "this_journal" + ], + "location_phrases" : [ + { + "language" : "en", + "phrase" : "Named Repository", + "value" : "named_repository" + }, + { + "phrase" : "Non-Commercial Repository", + "language" : "en", + "value" : "non_commercial_repository" + }, + { + "value" : "this_journal", + "language" : "en", + "phrase" : "This Journal" + } + ] + }, + "additional_oa_fee" : "yes" + }, + { + "location" : { + "named_repository" : [ + "PubMed Central", + "Research for Development Repository", + "ESRC Research Catalogue" + ], + "location" : [ + "institutional_repository", + "named_repository", + "subject_repository", + "this_journal" + ], + "location_phrases" : [ + { + "value" : "institutional_repository", + "phrase" : "Institutional Repository", + "language" : "en" + }, + { + "value" : "named_repository", + "language" : "en", + "phrase" : "Named Repository" + }, + { + "value" : "subject_repository", + "phrase" : "Subject Repository", + "language" : "en" + }, + { + "language" : "en", + "phrase" : "This Journal", + "value" : "this_journal" + } + ] + }, + "additional_oa_fee" : "yes", + "license" : [ + { + "license" : "cc_by", + "license_phrases" : [ + { + "language" : "en", + "phrase" : "CC BY", + "value" : "cc_by" + } + ] + } + ], + "article_version_phrases" : [ + { + "language" : "en", + "phrase" : "Published", + "value" : "published" + } + ], + "article_version" : [ + "published" + ], + "conditions" : [ + "Published source must be acknowledged with citation" + ], + "additional_oa_fee_phrases" : [ + { + "language" : "en", + "phrase" : "Yes", + "value" : "yes" + } + ] + } + ], + "urls" : [ + { + "url" : "https://www.elsevier.com/about/open-science/open-access", + "description" : "Open access" + }, + { + "description" : "Open access licenses", + "url" : "https://www.elsevier.com/about/policies/open-access-licenses" + } + ], + "uri" : "http://v2.sherpa.ac.uk/id/publisher_policy/3323", + "id" : 3323, + "publication_count" : 2102 + } + ], + "type" : "journal", + "title" : [ + { + "preferred_phrases" : [ + { + "language" : "en", + "phrase" : "Title", + "value" : "name" + } + ], + "preferred" : "name", + "title" : "The Lancet", + "language_phrases" : [ + { + "phrase" : "English", + "language" : "en", + "value" : "en" + } + ], + "language" : "en" + }, + { + "language" : "en", + "language_phrases" : [ + { + "language" : "en", + "phrase" : "English", + "value" : "en" + } + ], + "title" : "Lancet", + "preferred" : "name", + "preferred_phrases" : [ + { + "value" : "name", + "language" : "en", + "phrase" : "Title" + } + ] + } + ], + "listed_in_doaj_phrases" : [ + { + "language" : "en", + "phrase" : "No", + "value" : "no" + } + ] + } + ] +} \ No newline at end of file From d14699b0daa0450c41d2f2618334cb44f1195c6d Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Wed, 6 May 2020 12:53:26 +1200 Subject: [PATCH 032/179] [DS-3940](master) Configuration changes for new API key, URL, external svcs --- dspace/config/dspace.cfg | 13 ++++++++----- dspace/config/spring/api/external-services.xml | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index 91e7c11ea7..a094d46426 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -1456,12 +1456,15 @@ sitemap.engineurls = http://www.google.com/webmasters/sitemaps/ping?sitemap= sitemap.cron = 0 15 1 * * ? ##### SHERPA/Romeo Integration Settings #### -# the SHERPA/RoMEO endpoint -sherpa.romeo.url = http://www.sherpa.ac.uk/romeo/api29.php +# The SHERPA/RoMEO endpoint (v2 API) +sherpa.romeo.url = https://v2.sherpa.ac.uk/cgi/retrieve -# please register for a free api access key to get many benefits -# http://www.sherpa.ac.uk/news/romeoapikeys.htm -sherpa.romeo.apikey = +# Please register for a free api access key to use the SHERPA v2 API +# https://v2.sherpa.ac.uk/api/ +# Please note: the SHERPA v2 API uses different API keys to the legacy APIs. +# If you have been using the old ROMeO endpoint (end-of-life as at 2020-04-14), you must +# register for a new API key +#sherpa.romeo.apikey = YOUR-API-KEY ##### Authority Control Settings ##### #plugin.named.org.dspace.content.authority.ChoiceAuthority = \ diff --git a/dspace/config/spring/api/external-services.xml b/dspace/config/spring/api/external-services.xml index 2502f274d6..a53ce07016 100644 --- a/dspace/config/spring/api/external-services.xml +++ b/dspace/config/spring/api/external-services.xml @@ -5,14 +5,14 @@ - + - + From c2b2545f88c4e35ac08c5a4aa162eec274ef24ac Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Wed, 6 May 2020 12:58:03 +1200 Subject: [PATCH 033/179] [DS-3940](master) Removal of legacy v1 SHERPA classes and data providers --- .../dspace/app/sherpa/v1/SHERPAJournal.java | 49 ---- .../dspace/app/sherpa/v1/SHERPAPublisher.java | 175 ------------- .../dspace/app/sherpa/v1/SHERPAResponse.java | 206 ---------------- .../impl/SherpaJournalDataProvider.java | 232 ------------------ .../impl/SherpaPublisherDataProvider.java | 192 --------------- 5 files changed, 854 deletions(-) delete mode 100644 dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAJournal.java delete mode 100644 dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAPublisher.java delete mode 100644 dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAResponse.java delete mode 100644 dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaJournalDataProvider.java delete mode 100644 dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaPublisherDataProvider.java diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAJournal.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAJournal.java deleted file mode 100644 index 6cacfb8ad4..0000000000 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAJournal.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.app.sherpa.v1; - -/** - * POJO representation for a SHERPA journal - * - * @author Andrea Bollini - */ -public class SHERPAJournal { - private String title; - - private String issn; - - private String zetopub; - - private String romeopub; - - public SHERPAJournal(String title, String issn, String zetopub, - String romeopub) { - super(); - this.title = title; - this.issn = issn; - this.zetopub = zetopub; - this.romeopub = romeopub; - } - - public String getTitle() { - return title; - } - - public String getIssn() { - return issn; - } - - public String getZetopub() { - return zetopub; - } - - public String getRomeopub() { - return romeopub; - } - -} diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAPublisher.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAPublisher.java deleted file mode 100644 index 7f140978c3..0000000000 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAPublisher.java +++ /dev/null @@ -1,175 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.app.sherpa.v1; - -import java.util.List; - -/** - * POJO representation for a SHERPA Publisher record - * - * @author Andrea Bollini - */ -public class SHERPAPublisher { - - private String id; - - private String name; - - private String alias; - - private String homeurl; - - private String prearchiving; - - private List prerestriction; - - private String postarchiving; - - private List postrestriction; - - private String pubarchiving; - - private List pubrestriction; - - private List condition; - - private String paidaccessurl; - - private String paidaccessname; - - private String paidaccessnotes; - - private List copyright; - - private String romeocolour; - - private String dateadded; - - private String dateupdated; - - public SHERPAPublisher(String id, String name, String alias, String homeurl, - String prearchiving, List prerestriction, - String postarchiving, List postrestriction, - String pubarchiving, List pubrestriction, - List condition, String paidaccessurl, - String paidaccessname, String paidaccessnotes, - List copyright, String romeocolour, String datedded, - String dateupdated) { - this.id = id; - - this.name = name; - - this.alias = alias; - - this.homeurl = homeurl; - - this.prearchiving = prearchiving; - - this.prerestriction = prerestriction; - - this.postarchiving = postarchiving; - - this.postrestriction = postrestriction; - - this.pubarchiving = pubarchiving; - - this.pubrestriction = pubrestriction; - - this.condition = condition; - - this.paidaccessurl = paidaccessurl; - - this.paidaccessname = paidaccessname; - - this.paidaccessnotes = paidaccessnotes; - - this.copyright = copyright; - - this.romeocolour = romeocolour; - - this.dateadded = datedded; - - this.dateupdated = dateupdated; - } - - public String getName() { - return name; - } - - public String getAlias() { - return alias; - } - - public String getHomeurl() { - return homeurl; - } - - public String getPrearchiving() { - return prearchiving; - } - - public List getPrerestriction() { - return prerestriction; - } - - public String getPostarchiving() { - return postarchiving; - } - - public List getPostrestriction() { - return postrestriction; - } - - public String getPubarchiving() { - return pubarchiving; - } - - public List getPubrestriction() { - return pubrestriction; - } - - public List getCondition() { - return condition; - } - - public String getPaidaccessurl() { - return paidaccessurl; - } - - public String getPaidaccessname() { - return paidaccessname; - } - - public String getPaidaccessnotes() { - return paidaccessnotes; - } - - public List getCopyright() { - return copyright; - } - - public String getRomeocolour() { - return romeocolour; - } - - public String getDatedded() { - return dateadded; - } - - public String getDateupdated() { - return dateupdated; - } - - /** - * Generic getter for the id - * @return the id value of this SHERPAPublisher - */ - public String getId() { - return id; - } -} diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAResponse.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAResponse.java deleted file mode 100644 index 0e8d80ec41..0000000000 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v1/SHERPAResponse.java +++ /dev/null @@ -1,206 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.app.sherpa.v1; - -import java.io.InputStream; -import java.util.LinkedList; -import java.util.List; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.Logger; -import org.dspace.app.util.XMLUtils; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -/** - * JAVA representation for a SHERPA API Response - * - * @author Andrea Bollini - */ -public class SHERPAResponse { - private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(SHERPAResponse.class); - - private int numHits; - - private String message; - - private String license; - - private String licenseURL; - - private String disclaimer; - - private List journals; - - private List publishers; - - public SHERPAResponse(InputStream xmlData) { - try { - DocumentBuilderFactory factory = DocumentBuilderFactory - .newInstance(); - factory.setValidating(false); - factory.setIgnoringComments(true); - factory.setIgnoringElementContentWhitespace(true); - // disallow DTD parsing to ensure no XXE attacks can occur. - // See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html - factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - - DocumentBuilder db = factory.newDocumentBuilder(); - Document inDoc = db.parse(xmlData); - - Element xmlRoot = inDoc.getDocumentElement(); - Element headersElement = XMLUtils.getSingleElement(xmlRoot, - "header"); - Element journalsElement = XMLUtils.getSingleElement(xmlRoot, - "journals"); - Element publishersElement = XMLUtils.getSingleElement(xmlRoot, - "publishers"); - - String numhitsString = XMLUtils.getElementValue(headersElement, "numhits"); - if (StringUtils.isNotBlank(numhitsString)) { - numHits = Integer.parseInt(numhitsString); - } else { - numHits = 0; - } - message = XMLUtils.getElementValue(headersElement, "message"); - - license = XMLUtils.getElementValue(headersElement, "license"); - licenseURL = XMLUtils.getElementValue(headersElement, "licenseurl"); - disclaimer = XMLUtils.getElementValue(headersElement, "disclaimer"); - - List journalsList = XMLUtils.getElementList( - journalsElement, "journal"); - List publishersList = XMLUtils.getElementList( - publishersElement, "publisher"); - - if (journalsList != null) { - journals = new LinkedList(); - for (Element journalElement : journalsList) { - journals.add(new SHERPAJournal( - XMLUtils.getElementValue(journalElement, "jtitle"), - XMLUtils.getElementValue(journalElement, "issn"), - XMLUtils.getElementValue(journalElement, "zetopub"), - XMLUtils.getElementValue(journalElement, "romeopub"))); - } - } - - if (publishersList != null) { - publishers = new LinkedList(); - for (Element publisherElement : publishersList) { - Element preprintsElement = XMLUtils.getSingleElement( - publisherElement, "preprints"); - Element preprintsRestrictionElement = XMLUtils - .getSingleElement(publisherElement, - "prerestrictions"); - - Element postprintsElement = XMLUtils.getSingleElement( - publisherElement, "postprints"); - Element postprintsRestrictionElement = XMLUtils - .getSingleElement(publisherElement, - "postrestrictions"); - - Element pdfversionElement = XMLUtils.getSingleElement( - publisherElement, "pdfversion"); - Element pdfversionRestrictionElement = XMLUtils - .getSingleElement(publisherElement, - "pdfrestrictions"); - - Element conditionsElement = XMLUtils.getSingleElement( - publisherElement, "conditions"); - Element paidaccessElement = XMLUtils.getSingleElement( - publisherElement, "paidaccess"); - - Element copyrightlinksElement = XMLUtils.getSingleElement( - publisherElement, "copyrightlinks"); - publishers - .add(new SHERPAPublisher(publisherElement.getAttribute("id"), XMLUtils.getElementValue( - publisherElement, "name"), - XMLUtils.getElementValue(publisherElement, - "alias"), XMLUtils.getElementValue( - publisherElement, "homeurl"), - - XMLUtils.getElementValue(preprintsElement, - "prearchiving"), - XMLUtils.getElementValueList( - preprintsRestrictionElement, - "prerestriction"), - - XMLUtils.getElementValue(postprintsElement, - "postarchiving"), - XMLUtils.getElementValueList( - postprintsRestrictionElement, - "postrestriction"), - - XMLUtils.getElementValue(pdfversionElement, - "pdfarchiving"), - XMLUtils.getElementValueList( - pdfversionRestrictionElement, - "pdfrestriction"), - - XMLUtils - .getElementValueList( - conditionsElement, - "condition"), XMLUtils - .getElementValue(paidaccessElement, - "paidaccessurl"), XMLUtils - .getElementValue(paidaccessElement, - "paidaccessname"), XMLUtils - .getElementValue(paidaccessElement, - "paidaccessnotes"), - XMLUtils.getElementValueArrayList( - copyrightlinksElement, - "copyrightlink", - "copyrightlinktext", - "copyrightlinkurl"), XMLUtils - .getElementValue(publisherElement, - "romeocolour"), XMLUtils - .getElementValue(publisherElement, - "dateadded"), XMLUtils - .getElementValue(publisherElement, - "dateupdated"))); - } - } - } catch (Exception e) { - log.error("Error parsing SHERPA API Response", e); - } - } - - public SHERPAResponse(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - - public String getLicense() { - return license; - } - - public String getLicenseURL() { - return licenseURL; - } - - public String getDisclaimer() { - return disclaimer; - } - - public List getJournals() { - return journals; - } - - public List getPublishers() { - return publishers; - } - - public int getNumHits() { - return numHits; - } -} diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaJournalDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaJournalDataProvider.java deleted file mode 100644 index dc5a642458..0000000000 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaJournalDataProvider.java +++ /dev/null @@ -1,232 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.external.provider.impl; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.client.utils.URLEncodedUtils; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.message.BasicNameValuePair; -import org.apache.logging.log4j.Logger; -import org.dspace.app.sherpa.v1.SHERPAJournal; -import org.dspace.app.sherpa.v1.SHERPAResponse; -import org.dspace.content.dto.MetadataValueDTO; -import org.dspace.external.model.ExternalDataObject; -import org.dspace.external.provider.ExternalDataProvider; - -/** - * This class is the implementation of the ExternalDataProvider interface that - * will deal with SherpaJournal External data lookups. - */ -public class SherpaJournalDataProvider implements ExternalDataProvider { - - private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(SherpaJournalDataProvider.class); - - private String url; - private String sourceIdentifier; - private String apiKey; - - private CloseableHttpClient client = null; - - @Override - public String getSourceIdentifier() { - return sourceIdentifier; - } - - /** - * Initialise the client that we need to call the endpoint - * @throws IOException If something goes wrong - */ - public void init() throws IOException { - HttpClientBuilder builder = HttpClientBuilder.create(); - // httpclient 4.3+ doesn't appear to have any sensible defaults any more. Setting conservative defaults as - // not to hammer the SHERPA service too much. - client = builder - .disableAutomaticRetries() - .setMaxConnTotal(5) - .build(); - } - - @Override - public Optional getExternalDataObject(String id) { - - HttpGet method = null; - SHERPAResponse sherpaResponse = null; - int timeout = 5000; - URIBuilder uriBuilder = null; - try { - uriBuilder = new URIBuilder(url); - uriBuilder.addParameter("jtitle", id); - if (StringUtils.isNotBlank(apiKey)) { - uriBuilder.addParameter("ak", apiKey); - } - - method = new HttpGet(uriBuilder.build()); - method.setConfig(RequestConfig.custom() - .setConnectionRequestTimeout(timeout) - .setConnectTimeout(timeout) - .setSocketTimeout(timeout) - .build()); - // Execute the method. - - HttpResponse response = client.execute(method); - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode != HttpStatus.SC_OK) { - sherpaResponse = new SHERPAResponse("SHERPA/RoMEO return not OK status: " - + statusCode); - } - - HttpEntity responseBody = response.getEntity(); - - if (null != responseBody) { - sherpaResponse = new SHERPAResponse(responseBody.getContent()); - } else { - sherpaResponse = new SHERPAResponse("SHERPA/RoMEO returned no response"); - } - } catch (Exception e) { - log.error("SHERPA/RoMEO query failed: ", e); - } - - if (sherpaResponse == null) { - sherpaResponse = new SHERPAResponse( - "Error processing the SHERPA/RoMEO answer"); - } - if (CollectionUtils.isNotEmpty(sherpaResponse.getJournals())) { - SHERPAJournal sherpaJournal = sherpaResponse.getJournals().get(0); - - ExternalDataObject externalDataObject = constructExternalDataObjectFromSherpaJournal(sherpaJournal); - return Optional.of(externalDataObject); - } - return null; - } - - private ExternalDataObject constructExternalDataObjectFromSherpaJournal(SHERPAJournal sherpaJournal) { - ExternalDataObject externalDataObject = new ExternalDataObject(); - externalDataObject.setSource(sourceIdentifier); - externalDataObject.setId(sherpaJournal.getTitle()); - externalDataObject - .addMetadata(new MetadataValueDTO("dc", "title", null, null, sherpaJournal.getTitle())); - externalDataObject - .addMetadata(new MetadataValueDTO("dc", "identifier", "issn", null, sherpaJournal.getIssn())); - externalDataObject.setValue(sherpaJournal.getTitle()); - externalDataObject.setDisplayValue(sherpaJournal.getTitle()); - return externalDataObject; - } - - @Override - public List searchExternalDataObjects(String query, int start, int limit) { - // query args to add to SHERPA/RoMEO request URL - HttpGet get = constructHttpGet(query); - try ( CloseableHttpClient hc = HttpClientBuilder.create().build(); ) { - HttpResponse response = hc.execute(get); - if (response.getStatusLine().getStatusCode() == 200) { - - SHERPAResponse sherpaResponse = new SHERPAResponse(response.getEntity().getContent()); - List list = sherpaResponse.getJournals().stream().map( - sherpaJournal -> constructExternalDataObjectFromSherpaJournal(sherpaJournal)).collect( - Collectors.toList()); - // This is because Sherpa returns everything by default so we can't specifiy a start and limit - // in the query itself - return list.subList(start, Math.min(start + limit, list.size())); - } - } catch (IOException e) { - log.error("SHERPA/RoMEO query failed: ", e); - return Collections.emptyList(); - } finally { - get.releaseConnection(); - } - return Collections.emptyList(); - } - - private HttpGet constructHttpGet(String query) { - List args = new ArrayList<>(); - args.add(new BasicNameValuePair("jtitle", query)); - args.add(new BasicNameValuePair("qtype", "contains")); - args.add(new BasicNameValuePair("ak", apiKey)); - String srUrl = url + "?" + URLEncodedUtils.format(args, "UTF8"); - return new HttpGet(srUrl); - } - - @Override - public boolean supports(String source) { - return StringUtils.equalsIgnoreCase(sourceIdentifier, source); - } - - @Override - public int getNumberOfResults(String query) { - HttpGet get = constructHttpGet(query); - try ( CloseableHttpClient hc = HttpClientBuilder.create().build(); ) { - HttpResponse response = hc.execute(get); - if (response.getStatusLine().getStatusCode() == 200) { - SHERPAResponse sherpaResponse = new SHERPAResponse(response.getEntity().getContent()); - return sherpaResponse.getNumHits(); - } - } catch (IOException e) { - log.error("SHERPA/RoMEO query failed: ", e); - return 0; - } finally { - get.releaseConnection(); - } - return 0; - } - - /** - * Generic setter for the sourceIdentifier - * @param sourceIdentifier The sourceIdentifier to be set on this SherpaJournalDataProvider - */ - public void setSourceIdentifier(String sourceIdentifier) { - this.sourceIdentifier = sourceIdentifier; - } - - /** - * Generic getter for the url - * @return the url value of this SherpaJournalDataProvider - */ - public String getUrl() { - return url; - } - - /** - * Generic setter for the url - * @param url The url to be set on this SherpaJournalDataProvider - */ - public void setUrl(String url) { - this.url = url; - } - - /** - * Generic getter for the apiKey - * @return the apiKey value of this SherpaJournalDataProvider - */ - public String getApiKey() { - return apiKey; - } - - /** - * Generic setter for the apiKey - * @param apiKey The apiKey to be set on this SherpaJournalDataProvider - */ - public void setApiKey(String apiKey) { - this.apiKey = apiKey; - } -} diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaPublisherDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaPublisherDataProvider.java deleted file mode 100644 index c13fe0a675..0000000000 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SherpaPublisherDataProvider.java +++ /dev/null @@ -1,192 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.external.provider.impl; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.http.HttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URLEncodedUtils; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.message.BasicNameValuePair; -import org.apache.logging.log4j.Logger; -import org.dspace.app.sherpa.v1.SHERPAPublisher; -import org.dspace.app.sherpa.v1.SHERPAResponse; -import org.dspace.content.dto.MetadataValueDTO; -import org.dspace.external.model.ExternalDataObject; -import org.dspace.external.provider.ExternalDataProvider; - -/** - * This class is the implementation of the ExternalDataProvider interface that - * will deal with SherpaPublisher External data lookups. - */ -public class SherpaPublisherDataProvider implements ExternalDataProvider { - - private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(SherpaPublisherDataProvider.class); - - private String sourceIdentifier; - private String url; - private String apiKey; - - @Override - public String getSourceIdentifier() { - return sourceIdentifier; - } - - @Override - public Optional getExternalDataObject(String id) { - List args = new ArrayList<>(); - args.add(new BasicNameValuePair("id", id)); - args.add(new BasicNameValuePair("ak", apiKey)); - String srUrl = url + "?" + URLEncodedUtils.format(args, "UTF8"); - HttpGet get = new HttpGet(srUrl); - try ( CloseableHttpClient hc = HttpClientBuilder.create().build(); ) { - HttpResponse response = hc.execute(get); - if (response.getStatusLine().getStatusCode() == 200) { - SHERPAResponse sherpaResponse = new SHERPAResponse(response.getEntity().getContent()); - List list = sherpaResponse.getPublishers(); - if (CollectionUtils.isNotEmpty(list)) { - return Optional.of(constructExternalDataObjectFromSherpaPublisher(list.get(0))); - } - } - } catch (IOException e) { - log.error("SHERPA/RoMEO query failed: ", e); - return null; - } finally { - get.releaseConnection(); - } - return null; - } - - @Override - public List searchExternalDataObjects(String query, int start, int limit) { - HttpGet get = constructHttpGet(query); - try ( CloseableHttpClient hc = HttpClientBuilder.create().build(); ) { - HttpResponse response = hc.execute(get); - if (response.getStatusLine().getStatusCode() == 200) { - SHERPAResponse sherpaResponse = new SHERPAResponse(response.getEntity().getContent()); - List list = sherpaResponse.getPublishers().stream().map( - sherpaPublisher -> constructExternalDataObjectFromSherpaPublisher(sherpaPublisher)).collect( - Collectors.toList()); - - // This is because Sherpa returns everything by default so we can't specifiy a start and limit - // in the query itself - return list.subList(start, Math.min(start + limit, list.size())); - } - } catch (IOException e) { - log.error("SHERPA/RoMEO query failed: ", e); - return Collections.emptyList(); - } finally { - get.releaseConnection(); - } - return Collections.emptyList(); - } - - private HttpGet constructHttpGet(String query) { - List args = new ArrayList<>(); - args.add(new BasicNameValuePair("pub", query)); - args.add(new BasicNameValuePair("qtype", "all")); - args.add(new BasicNameValuePair("ak", apiKey)); - String srUrl = url + "?" + URLEncodedUtils.format(args, "UTF8"); - return new HttpGet(srUrl); - } - - private ExternalDataObject constructExternalDataObjectFromSherpaPublisher(SHERPAPublisher sherpaPublisher) { - ExternalDataObject externalDataObject = new ExternalDataObject(); - externalDataObject.setSource(sourceIdentifier); - - //Text value == name - externalDataObject.addMetadata(new MetadataValueDTO("dc", "title", null, null, sherpaPublisher.getName())); - externalDataObject.setDisplayValue(sherpaPublisher.getName()); - externalDataObject.setValue(sherpaPublisher.getName()); - if (StringUtils.isNotBlank(sherpaPublisher.getId())) { - externalDataObject.setId(sherpaPublisher.getId()); - externalDataObject - .addMetadata( - new MetadataValueDTO("dc", "identifier", "sherpaPublisher", null, sherpaPublisher.getId())); - } - - //Text value == homeurl - externalDataObject - .addMetadata(new MetadataValueDTO("dc", "identifier", "other", null, sherpaPublisher.getHomeurl())); - - return externalDataObject; - } - - @Override - public boolean supports(String source) { - return StringUtils.equalsIgnoreCase(sourceIdentifier, source); - } - - @Override - public int getNumberOfResults(String query) { - HttpGet get = constructHttpGet(query); - try ( CloseableHttpClient hc = HttpClientBuilder.create().build(); ) { - HttpResponse response = hc.execute(get); - if (response.getStatusLine().getStatusCode() == 200) { - - SHERPAResponse sherpaResponse = new SHERPAResponse(response.getEntity().getContent()); - return sherpaResponse.getNumHits(); - } - } catch (IOException e) { - log.error("SHERPA/RoMEO query failed: ", e); - return 0; - } finally { - get.releaseConnection(); - } - return 0; - } - - /** - * Generic setter for the sourceIdentifier - * @param sourceIdentifier The sourceIdentifier to be set on this SherpaPublisherDataProvider - */ - public void setSourceIdentifier(String sourceIdentifier) { - this.sourceIdentifier = sourceIdentifier; - } - - /** - * Generic getter for the url - * @return the url value of this SherpaPublisherDataProvider - */ - public String getUrl() { - return url; - } - - /** - * Generic setter for the url - * @param url The url to be set on this SherpaPublisherDataProvider - */ - public void setUrl(String url) { - this.url = url; - } - - /** - * Generic getter for the apiKey - * @return the apiKey value of this SherpaPublisherDataProvider - */ - public String getApiKey() { - return apiKey; - } - - /** - * Generic setter for the apiKey - * @param apiKey The apiKey to be set on this SherpaPublisherDataProvider - */ - public void setApiKey(String apiKey) { - this.apiKey = apiKey; - } -} From 0b10f1971b825d1d9c8d232f043c05be17539931 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Wed, 6 May 2020 13:53:42 +1200 Subject: [PATCH 034/179] [DS-3940](master) Better handling of empty / null results in providers --- .../external/provider/impl/SHERPAv2JournalDataProvider.java | 5 +++-- .../provider/impl/SHERPAv2PublisherDataProvider.java | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java index ba0bc2ad89..7bf8b5fe9a 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java @@ -10,6 +10,7 @@ package org.dspace.external.provider.impl; import java.io.IOException; import java.io.InputStream; import java.net.URISyntaxException; +import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -140,7 +141,7 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { ExternalDataObject externalDataObject = constructExternalDataObjectFromSherpaJournal(sherpaJournal); return Optional.of(externalDataObject); } - return null; + return Optional.empty(); } /** @@ -218,7 +219,7 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { get.releaseConnection(); } } - return null; + return Collections.emptyList(); } /** diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java index d24ca6d039..be35ca3105 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java @@ -10,6 +10,7 @@ package org.dspace.external.provider.impl; import java.io.IOException; import java.io.InputStream; import java.net.URISyntaxException; +import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -142,7 +143,7 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { ExternalDataObject externalDataObject = constructExternalDataObjectFromSherpaPublisher(sherpaPublisher); return Optional.of(externalDataObject); } - return null; + return Optional.empty(); } /** @@ -192,7 +193,7 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { get.releaseConnection(); } } - return null; + return Collections.emptyList(); } /** From 54ec03d0a1595fec621416c0e637f6842750ff18 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Thu, 28 May 2020 09:47:11 +1200 Subject: [PATCH 035/179] [DS-3940](master) Ensure sherpa.romeo.apikey placeholder always exists Spring bean configuration (external-sources.xml) requires the placeholder, even if it is null, so this change reverts the commented out api key introduced with other v2 refactor work --- dspace/config/dspace.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index a094d46426..e61c31e5d6 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -1464,7 +1464,7 @@ sherpa.romeo.url = https://v2.sherpa.ac.uk/cgi/retrieve # Please note: the SHERPA v2 API uses different API keys to the legacy APIs. # If you have been using the old ROMeO endpoint (end-of-life as at 2020-04-14), you must # register for a new API key -#sherpa.romeo.apikey = YOUR-API-KEY +sherpa.romeo.apikey = ##### Authority Control Settings ##### #plugin.named.org.dspace.content.authority.ChoiceAuthority = \ From 7fffe96a6ab0207b573b2874acc00aa44fedfeee Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Thu, 28 May 2020 11:25:58 +1200 Subject: [PATCH 036/179] [DS-3940](master) Add license headers to unit test classes --- .../dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java | 7 +++++++ .../java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java b/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java index 57715e83d4..a31313620a 100644 --- a/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java +++ b/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java @@ -1,3 +1,10 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ package org.dspace.app.sherpa.v2; import static org.junit.Assert.assertEquals; diff --git a/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java b/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java index 285f0c67ed..c1dbdc5eca 100644 --- a/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java +++ b/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java @@ -1,3 +1,10 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ package org.dspace.app.sherpa.v2; import java.io.IOException; From e2f38fb25764a7394ee4054db007e6d226d4cd90 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Thu, 28 May 2020 13:11:59 +1200 Subject: [PATCH 037/179] [DS-3940](master) Fixes for Checkstyle failures in unit tests (imports, whitespace after catch) --- .../app/sherpa/v2/SHERPAPublisherResponseTest.java | 6 ++++-- .../org/dspace/app/sherpa/v2/SHERPAResponseTest.java | 12 +++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java b/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java index a31313620a..25676b93fd 100644 --- a/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java +++ b/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java @@ -14,7 +14,6 @@ import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.InputStream; - import org.apache.commons.collections4.CollectionUtils; import org.dspace.AbstractDSpaceTest; import org.junit.After; @@ -23,6 +22,9 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +/** + * @author Kim Shepherd + */ public class SHERPAPublisherResponseTest extends AbstractDSpaceTest { public SHERPAPublisherResponseTest() { @@ -84,7 +86,7 @@ public class SHERPAPublisherResponseTest extends AbstractDSpaceTest { assertEquals("Response publisher ID did not match expected ID " + expectedId, expectedId, response.getPublishers().get(0).getIdentifier()); - } catch(IOException e) { + } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } finally { if (content != null) { diff --git a/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java b/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java index c1dbdc5eca..d171a8b77a 100644 --- a/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java +++ b/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java @@ -7,21 +7,23 @@ */ package org.dspace.app.sherpa.v2; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import java.io.IOException; import java.io.InputStream; import org.apache.commons.collections4.CollectionUtils; import org.dspace.AbstractDSpaceTest; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertFalse; - import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +/** + * @author Kim Shepherd + */ public class SHERPAResponseTest extends AbstractDSpaceTest { public SHERPAResponseTest() { @@ -94,7 +96,7 @@ public class SHERPAResponseTest extends AbstractDSpaceTest { String expectedPublisherName = "Elsevier"; assertTrue("Response did not contain expected publisher name '" + expectedPublisherName + "'", expectedPublisherName.equals(response.getJournals().get(0).getPublisher().getName())); - } catch(IOException e) { + } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } finally { if (content != null) { From 1b40dff96aa9554f82ee11080562044a217fa29a Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Wed, 17 Jun 2020 15:43:29 +1200 Subject: [PATCH 038/179] [DS-3940](main) Replace '200' with HttpStatus.SC_OK in data providers --- .../external/provider/impl/SHERPAv2JournalDataProvider.java | 4 ++-- .../external/provider/impl/SHERPAv2PublisherDataProvider.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java index 7bf8b5fe9a..85c8ef660c 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java @@ -188,7 +188,7 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { get = constructHttpGet(query, start, limit); HttpClient hc = new DefaultHttpClient(); HttpResponse response = hc.execute(get); - if (response.getStatusLine().getStatusCode() == 200) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { // Get response input stream and parse JSON into new SHERPAResponse object InputStream content = null; try { @@ -287,7 +287,7 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { get = constructHttpGet(query); HttpClient hc = new DefaultHttpClient(); HttpResponse response = hc.execute(get); - if (response.getStatusLine().getStatusCode() == 200) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { // Read response and parse as SHERPAResponse object InputStream content = null; try { diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java index be35ca3105..417daaf535 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java @@ -161,7 +161,7 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { get = constructHttpGet(query, start, limit); HttpClient hc = new DefaultHttpClient(); HttpResponse response = hc.execute(get); - if (response.getStatusLine().getStatusCode() == 200) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { // Get response input stream and parse JSON into new SHERPAResponse object InputStream content = null; try { @@ -289,7 +289,7 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { get = constructHttpGet(query); HttpClient hc = new DefaultHttpClient(); HttpResponse response = hc.execute(get); - if (response.getStatusLine().getStatusCode() == 200) { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { // Read response and parse as SHERPAResponse object InputStream content = null; try { From a8bdc5f09a43851eaf1b8c4f445530b90f456374 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Wed, 17 Jun 2020 16:02:47 +1200 Subject: [PATCH 039/179] [DS-3940](main) Add basic javadoc for new SHERPA data classes --- .../org/dspace/app/sherpa/v2/SHERPAJournal.java | 12 ++++++++++++ .../app/sherpa/v2/SHERPAPermittedVersion.java | 16 ++++++++++++++++ .../dspace/app/sherpa/v2/SHERPAPublisher.java | 11 +++++++++++ .../app/sherpa/v2/SHERPAPublisherPolicy.java | 12 ++++++++++++ .../app/sherpa/v2/SHERPAPublisherResponse.java | 4 +++- .../org/dspace/app/sherpa/v2/SHERPAResponse.java | 3 +++ .../app/sherpa/v2/SHERPASystemMetadata.java | 11 +++++++++++ 7 files changed, 68 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAJournal.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAJournal.java index d7693a1019..b668dbd927 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAJournal.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAJournal.java @@ -9,6 +9,18 @@ package org.dspace.app.sherpa.v2; import java.util.List; +/** + * Plain java representation of a SHERPA Journal object, based on SHERPA API v2 responses. + * + * In a SHERPA search for journal deposit policies, this is generally structured + * as a list in the SHERPAResponse object. + * Each journal contains a list of publisher data and list of publishing policies as well as basic metadata + * about the journal such as ISSNs, titles, whether it appears in DOAJ, primary publisher, etc. + * @see SHERPAResponse + * @see org.dspace.external.provider.impl.SHERPAv2JournalDataProvider + * + * @author Kim Shepherd + */ public class SHERPAJournal { private List titles; diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java index 9d18a87bb7..dca04b2bb9 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java @@ -9,6 +9,22 @@ package org.dspace.app.sherpa.v2; import java.util.List; +/** + * Plain java representation of a SHERPA Permitted Version object, based on SHERPA API v2 responses. + * + * In a SHERPA search for journal deposit policies, this data is contained within a publisher policy. + * Each permitted version is for a particular article version (eg. submitted, accepted, published) and contains + * + * A list of general conditions / terms for deposit of this version of work + * A list of allowed locations (eg. institutional repository, personal homepage, non-commercial repository) + * A list of prerequisite conditions for deposit (eg. attribution, linking to published version) + * A list of required licences for the deposited work (eg. CC-BY-NC) + * Embargo requirements, if any + * + * This class also has some helper data for labels, which can be used with i18n when displaying policy information + * + * @see SHERPAPublisherPolicy + */ public class SHERPAPermittedVersion { // Version (submitted, accepted, published) diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisher.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisher.java index d874e00434..0097ec2fb3 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisher.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisher.java @@ -7,6 +7,17 @@ */ package org.dspace.app.sherpa.v2; +/** + * Plain java representation of a SHERPA Publisher object, based on SHERPA API v2 responses. + * + * In a search for SHERPA journal deposit policy, this publisher object will appear in a list of publishers + * from the journal object, and as a single publisher member for the primary/current publisher of the journal. + * In a search for SHERPA publisher information, this object will appear in a list of publishers from the main + * SHERPA Publisher Response object + * + * @see SHERPAJournal + * @see SHERPAPublisherResponse + */ public class SHERPAPublisher { private String name = null; private String relationshipType; diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherPolicy.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherPolicy.java index 5502389bb2..2a04564e28 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherPolicy.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherPolicy.java @@ -10,6 +10,18 @@ package org.dspace.app.sherpa.v2; import java.util.List; import java.util.Map; +/** + * Plain java representation of a SHERPA Publisher Policy object, based on SHERPA API v2 responses. + * + * In a SHERPA search for deposit policies, each journal contains one or more publisher policies + * Each publisher policies contains a list of different article versions (eg. submitted, accepted, published) + * which hold the data about what can be done with each version. + * This class also holds copyright URLs and other policy URLs, as well as some helper information for display + * of overall policies in UI (as per legacy SHERPA data) + * + * @see SHERPAJournal + * @see SHERPAPermittedVersion + */ public class SHERPAPublisherPolicy { private int id; diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponse.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponse.java index 054600ab68..326ae9e083 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponse.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponse.java @@ -22,7 +22,9 @@ import org.json.JSONTokener; /** * Model class for the SHERPAv2 API (JSON) response for a publisher search * The structure and approached used is quite different to the simple v1 API used previously - * + * + * @see SHERPAPublisher + * * @author Kim Shepherd * */ diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java index 34208ff788..468e8c0001 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java @@ -26,6 +26,9 @@ import org.json.JSONTokener; /** * Model class for the SHERPAv2 API (JSON) response for a publication (journal) search * The structure and approached used is quite different to the simple v1 API used previously + * The structure is based on journal data, which in turn contains data about publishers and policies + * + * @see SHERPAJournal * * @author Kim Shepherd * diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPASystemMetadata.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPASystemMetadata.java index c79eb81d4d..2a807940bb 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPASystemMetadata.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPASystemMetadata.java @@ -7,6 +7,17 @@ */ package org.dspace.app.sherpa.v2; +/** + * Plain java representation of a SHERPA System Metadata object, based on SHERPA API v2 responses. + * + * This data is included in both journal deposit policy and publisher searches and contains basic metadata + * about the SHERPA record and API response, eg. creation and modification dates, internal IDs, permissions, etc. + * + * @see SHERPAResponse + * @see SHERPAPublisherResponse + * + * @author Kim Shepherd + */ public class SHERPASystemMetadata { private int id; From 43d7c20fd2474f5bea953911d595e25f01aca983 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Sun, 21 Jun 2020 14:09:21 +1200 Subject: [PATCH 040/179] [DS-3940](main) Shift spring config to DSpace config service for providers --- .../impl/SHERPAv2JournalDataProvider.java | 37 +++---------------- .../impl/SHERPAv2PublisherDataProvider.java | 37 +++---------------- .../config/spring/api/external-services.xml | 10 +---- 3 files changed, 13 insertions(+), 71 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java index 85c8ef660c..62a5d983a0 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java @@ -33,6 +33,7 @@ import org.dspace.app.sherpa.v2.SHERPAResponse; import org.dspace.content.dto.MetadataValueDTO; import org.dspace.external.model.ExternalDataObject; import org.dspace.external.provider.ExternalDataProvider; +import org.dspace.services.factory.DSpaceServicesFactory; /** * This class is the implementation of the ExternalDataProvider interface that will deal with SherpaJournal External @@ -68,6 +69,11 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { .disableAutomaticRetries() .setMaxConnTotal(5) .build(); + + // Initialise API key and base URL from configuration service + apiKey = DSpaceServicesFactory.getInstance().getConfigurationService().getProperty("sherpa.romeo.apikey"); + url = DSpaceServicesFactory.getInstance().getConfigurationService().getProperty("sherpa.romeo.url", + "https://v2.sherpa.ac.uk/cgi/retrieve"); } /** @@ -324,35 +330,4 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { this.sourceIdentifier = sourceIdentifier; } - /** - * Generic getter for the url - * @return the url value of this SherpaJournalDataProvider - */ - public String getUrl() { - return url; - } - - /** - * Generic setter for the url - * @param url The url to be set on this SHERPAv2JournalDataProvider - */ - public void setUrl(String url) { - this.url = url; - } - - /** - * Generic getter for the apiKey - * @return the apiKey value of this SHERPAv2JournalDataProvider - */ - public String getApiKey() { - return apiKey; - } - - /** - * Generic setter for the apiKey - * @param apiKey The apiKey to be set on this SHERPAv2JournalDataProvider - */ - public void setApiKey(String apiKey) { - this.apiKey = apiKey; - } } diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java index 417daaf535..799a5fe65b 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java @@ -33,6 +33,7 @@ import org.dspace.app.sherpa.v2.SHERPAPublisherResponse; import org.dspace.content.dto.MetadataValueDTO; import org.dspace.external.model.ExternalDataObject; import org.dspace.external.provider.ExternalDataProvider; +import org.dspace.services.factory.DSpaceServicesFactory; /** * This class is the implementation of the ExternalDataProvider interface that will deal with SHERPAPublisher External @@ -71,6 +72,11 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { .disableAutomaticRetries() .setMaxConnTotal(5) .build(); + + // Initialise API key and base URL from configuration service + apiKey = DSpaceServicesFactory.getInstance().getConfigurationService().getProperty("sherpa.romeo.apikey"); + url = DSpaceServicesFactory.getInstance().getConfigurationService().getProperty("sherpa.romeo.url", + "https://v2.sherpa.ac.uk/cgi/retrieve"); } /** @@ -327,35 +333,4 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { this.sourceIdentifier = sourceIdentifier; } - /** - * Generic getter for the url - * @return the url value of this SHERPAv2PublisherDataProvider - */ - public String getUrl() { - return url; - } - - /** - * Generic setter for the url - * @param url The url to be set on this SHERPAv2PublisherDataProvider - */ - public void setUrl(String url) { - this.url = url; - } - - /** - * Generic getter for the apiKey - * @return the apiKey value of this SHERPAv2PublisherDataProvider - */ - public String getApiKey() { - return apiKey; - } - - /** - * Generic setter for the apiKey - * @param apiKey The apiKey to be set on this SHERPAv2PublisherDataProvider - */ - public void setApiKey(String apiKey) { - this.apiKey = apiKey; - } } diff --git a/dspace/config/spring/api/external-services.xml b/dspace/config/spring/api/external-services.xml index a53ce07016..b9bdc7f33d 100644 --- a/dspace/config/spring/api/external-services.xml +++ b/dspace/config/spring/api/external-services.xml @@ -7,17 +7,9 @@ - - - - - + - - - - From b53d14eeaee3fd023b4019f10ec189d0873e7ebe Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Sun, 21 Jun 2020 14:58:32 +1200 Subject: [PATCH 041/179] [DS-3940](main) Sanitise query strings for SHERPA v2 API calls --- .../org/dspace/app/sherpa/SHERPAService.java | 4 ++ .../org/dspace/app/sherpa/v2/SHERPAUtils.java | 38 +++++++++++++++++++ .../impl/SHERPAv2JournalDataProvider.java | 8 ++++ .../impl/SHERPAv2PublisherDataProvider.java | 8 ++++ 4 files changed, 58 insertions(+) create mode 100644 dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAUtils.java diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java b/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java index b254788b47..f6b6df6da6 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java @@ -21,6 +21,7 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.logging.log4j.Logger; import org.dspace.app.sherpa.v2.SHERPAResponse; +import org.dspace.app.sherpa.v2.SHERPAUtils; import org.dspace.services.ConfigurationService; import org.springframework.beans.factory.annotation.Autowired; @@ -78,6 +79,9 @@ public class SHERPAService { try { Thread.sleep(sleepBetweenTimeouts); + // Sanitise query string + query = SHERPAUtils.sanitiseQuery(query); + URIBuilder uriBuilder = new URIBuilder(endpoint); uriBuilder.addParameter("item-type", "publication"); diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAUtils.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAUtils.java new file mode 100644 index 0000000000..08a0bc5e86 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAUtils.java @@ -0,0 +1,38 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.sherpa.v2; + +/** + * SHERPA v2 API query handling utility methods (static). Used by external data providers and SHERPA service. + * + * @author Kim Shepherd + */ +public final class SHERPAUtils { + + // Private constructor (since this is a Utility class) + private SHERPAUtils() {} + + /** + * Sanitise a SHERPA v2 API query for some special JSON characters to help with parsing at remote end + * Strip all these characters: "'{}; + * The URI builder used in the provider and service classes will perform URL encoding. This string + * is the raw query submitted to the provider or service. + * @param query query string + * @return safe query string + */ + public static String sanitiseQuery(String query) { + String safe = query; + try { + safe = query.replaceAll("['{}\";]", ""); + } catch (NullPointerException e) { + safe = ""; + } + return safe; + } + +} diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java index 62a5d983a0..cd1898c4ad 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java @@ -30,6 +30,7 @@ import org.apache.http.impl.client.HttpClientBuilder; import org.apache.logging.log4j.Logger; import org.dspace.app.sherpa.v2.SHERPAJournal; import org.dspace.app.sherpa.v2.SHERPAResponse; +import org.dspace.app.sherpa.v2.SHERPAUtils; import org.dspace.content.dto.MetadataValueDTO; import org.dspace.external.model.ExternalDataObject; import org.dspace.external.provider.ExternalDataProvider; @@ -88,6 +89,10 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { SHERPAResponse sherpaResponse = null; int timeout = 5000; URIBuilder uriBuilder = null; + + // Sanitise ID / title query string (strips some special characters) + id = SHERPAUtils.sanitiseQuery(id); + try { // Construct URI for an exact match on journal title uriBuilder = new URIBuilder(url); @@ -247,6 +252,9 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { * @throws URISyntaxException */ private HttpGet constructHttpGet(String query, int start, int limit) throws URISyntaxException { + // Sanitise query string (strip some characters) + query = SHERPAUtils.sanitiseQuery(query); + // Build URL based on search query URIBuilder uriBuilder = new URIBuilder(url); uriBuilder.addParameter("item-type", "publication"); diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java index 799a5fe65b..b80abdeec6 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java @@ -30,6 +30,7 @@ import org.apache.http.impl.client.HttpClientBuilder; import org.apache.logging.log4j.Logger; import org.dspace.app.sherpa.v2.SHERPAPublisher; import org.dspace.app.sherpa.v2.SHERPAPublisherResponse; +import org.dspace.app.sherpa.v2.SHERPAUtils; import org.dspace.content.dto.MetadataValueDTO; import org.dspace.external.model.ExternalDataObject; import org.dspace.external.provider.ExternalDataProvider; @@ -91,6 +92,10 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { SHERPAPublisherResponse sherpaResponse = null; int timeout = 5000; URIBuilder uriBuilder = null; + + // Escape the given ID / title query + id = SHERPAUtils.escapeQuery(id); + try { // Construct URI for an exact match on journal title uriBuilder = new URIBuilder(url); @@ -221,6 +226,9 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { * @throws URISyntaxException */ private HttpGet constructHttpGet(String query, int start, int limit) throws URISyntaxException { + // Escape query string + query = SHERPAUtils.escapeQuery(query); + // Build URL based on search query URIBuilder uriBuilder = new URIBuilder(url); uriBuilder.addParameter("item-type", "publisher"); From 6bed0894594e162c5616f14660bafee8d32db701 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Sun, 21 Jun 2020 15:35:28 +1200 Subject: [PATCH 042/179] [DS-3940](main) Sanitise query string (bugfix for bad method name in Pub) --- .../provider/impl/SHERPAv2PublisherDataProvider.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java index b80abdeec6..a4e7f32d5f 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java @@ -93,8 +93,8 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { int timeout = 5000; URIBuilder uriBuilder = null; - // Escape the given ID / title query - id = SHERPAUtils.escapeQuery(id); + // Sanitise the given ID / title query + id = SHERPAUtils.sanitiseQuery(id); try { // Construct URI for an exact match on journal title @@ -226,8 +226,8 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { * @throws URISyntaxException */ private HttpGet constructHttpGet(String query, int start, int limit) throws URISyntaxException { - // Escape query string - query = SHERPAUtils.escapeQuery(query); + // Sanitise the query string + query = SHERPAUtils.sanitiseQuery(query); // Build URL based on search query URIBuilder uriBuilder = new URIBuilder(url); From 50612a8334042044356ec5c72122a1dd2161fa9a Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Sun, 21 Jun 2020 15:37:26 +1200 Subject: [PATCH 043/179] [DS-3940](main) Rethrow IOExceptions that are caught within main try block --- .../external/provider/impl/SHERPAv2JournalDataProvider.java | 2 ++ .../external/provider/impl/SHERPAv2PublisherDataProvider.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java index cd1898c4ad..21c9adc621 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java @@ -216,6 +216,7 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { } } catch (IOException e) { log.error("Error parsing SHERPA response input stream: " + e.getMessage()); + throw new IOException(e); } finally { if (content != null) { content.close(); @@ -312,6 +313,7 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { } } catch (IOException e) { log.error("Error reading input stream for SHERPAResponse: " + e.getMessage()); + throw new IOException(e); } finally { if (content != null) { content.close(); diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java index a4e7f32d5f..7973e88d9a 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java @@ -190,6 +190,7 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { } } catch (IOException e) { log.error("Error parsing SHERPA response input stream: " + e.getMessage()); + throw new IOException(e); } finally { if (content != null) { content.close(); @@ -315,6 +316,7 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { } } catch (IOException e) { log.error("Error reading input stream for SHERPAResponse: " + e.getMessage()); + throw new IOException(e); } finally { if (content != null) { content.close(); From 038500b77260fbe6580cabfdd45eae8d24aaf640 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Sun, 21 Jun 2020 15:49:15 +1200 Subject: [PATCH 044/179] [DS-3940](main) Remove versionLabel from permittedVersion - just store key --- .../org/dspace/app/sherpa/v2/SHERPAResponse.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java index 468e8c0001..9bb1c89a23 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java @@ -17,7 +17,6 @@ import java.util.Map; import java.util.TreeMap; import org.apache.log4j.Logger; -import org.dspace.core.I18nUtil; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -386,8 +385,8 @@ public class SHERPAResponse { // submitted = preprint // accepted = postprint // published = pdfversion + // These strings can be used to construct i18n messages. String articleVersion = "unknown"; - String versionLabel = "Unknown"; if (permitted.has("article_version")) { JSONArray versions = permitted.getJSONArray("article_version"); @@ -396,14 +395,6 @@ public class SHERPAResponse { log.debug("Added allowed version: " + articleVersion + " to list"); } - if ("submitted".equals(articleVersion)) { - versionLabel = I18nUtil.getMessage("jsp.sherpa.submitted-version-label"); - } else if ("accepted".equals(articleVersion)) { - versionLabel = I18nUtil.getMessage("jsp.sherpa.accepted-version-label"); - } else if ("published".equals(articleVersion)) { - versionLabel = I18nUtil.getMessage("jsp.sherpa.published-version-label"); - } - // These are now child arrays, in old API they were explicit like // "preprint restrictions", etc., and just contained text rather than data if (permitted.has("conditions")) { @@ -415,8 +406,6 @@ public class SHERPAResponse { permittedVersion.setConditions(conditionList); } - permittedVersion.setArticleVersionLabel(versionLabel); - // Any prerequisites for this option (eg required by funder) List prerequisites = new ArrayList<>(); if (permitted.has("prerequisites")) { From 0f25bd96dafcf73011afe51c324e3c605b7001fd Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Sun, 21 Jun 2020 16:15:50 +1200 Subject: [PATCH 045/179] [DS-3940](main) Log response body in HTTP errors, err msg in submit service --- .../main/java/org/dspace/app/sherpa/SHERPAService.java | 4 ++++ .../dspace/app/sherpa/submit/SHERPASubmitService.java | 3 ++- .../provider/impl/SHERPAv2JournalDataProvider.java | 10 ++++++++++ .../provider/impl/SHERPAv2PublisherDataProvider.java | 10 ++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java b/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java index f6b6df6da6..245d372a61 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java @@ -9,7 +9,9 @@ package org.dspace.app.sherpa; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -107,6 +109,8 @@ public class SHERPAService { if (statusCode != HttpStatus.SC_OK) { sherpaResponse = new SHERPAResponse("SHERPA/RoMEO return not OK status: " + statusCode); + String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); + log.error("Error from SHERPA HTTP request: " + errorBody); } HttpEntity responseBody = response.getEntity(); diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/submit/SHERPASubmitService.java b/dspace-api/src/main/java/org/dspace/app/sherpa/submit/SHERPASubmitService.java index c171367941..1f0dbcefb1 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/submit/SHERPASubmitService.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/submit/SHERPASubmitService.java @@ -51,7 +51,8 @@ public class SHERPASubmitService { SHERPAResponse response = sherpaService.searchByJournalISSN(issn); if (response.isError()) { // Continue with loop - log.warn("Failed to look up SHERPA ROMeO result for ISSN: " + issn); + log.warn("Failed to look up SHERPA ROMeO result for ISSN: " + issn + + ": " + response.getMessage()); } // Store this response, even if it has an error (useful for UI reporting) responses.add(response); diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java index 21c9adc621..4fbdbf5aa0 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java @@ -10,12 +10,14 @@ package org.dspace.external.provider.impl; import java.io.IOException; import java.io.InputStream; import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -118,6 +120,8 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { if (statusCode != HttpStatus.SC_OK) { sherpaResponse = new SHERPAResponse("SHERPA/RoMEO return not OK status: " + statusCode); + String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); + log.error("Error from SHERPA HTTP request: " + errorBody); } HttpEntity responseBody = response.getEntity(); @@ -222,6 +226,9 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { content.close(); } } + } else { + String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); + log.error("Error from SHERPA HTTP request: " + errorBody); } } catch (IOException | URISyntaxException e) { log.error("SHERPA/RoMEO query failed: ", e); @@ -319,6 +326,9 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { content.close(); } } + } else { + String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); + log.error("Error from SHERPA HTTP request: " + errorBody); } } catch (IOException | URISyntaxException e) { log.error("SHERPA/RoMEO query failed: ", e); diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java index 7973e88d9a..905a1caa67 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java @@ -10,12 +10,14 @@ package org.dspace.external.provider.impl; import java.io.IOException; import java.io.InputStream; import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -121,6 +123,8 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { if (statusCode != HttpStatus.SC_OK) { sherpaResponse = new SHERPAPublisherResponse("SHERPA/RoMEO return not OK status: " + statusCode); + String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); + log.error("Error from SHERPA HTTP request: " + errorBody); } HttpEntity responseBody = response.getEntity(); @@ -196,6 +200,9 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { content.close(); } } + } else { + String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); + log.error("Error from SHERPA HTTP request: " + errorBody); } } catch (IOException | URISyntaxException e) { log.error("SHERPA/RoMEO query failed: ", e); @@ -322,6 +329,9 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { content.close(); } } + } else { + String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); + log.error("Error from SHERPA HTTP request: " + errorBody); } } catch (IOException | URISyntaxException e) { log.error("SHERPA/RoMEO query failed: ", e); From 7b01dcf822d3fc32f6bc1a245fad3933086b245f Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Wed, 24 Jun 2020 12:51:06 +1200 Subject: [PATCH 046/179] [DS-3940](main) Remove version label, getter, setter from PermittedVersion --- .../dspace/app/sherpa/v2/SHERPAPermittedVersion.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java index dca04b2bb9..ec45a29ce7 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java @@ -30,9 +30,6 @@ public class SHERPAPermittedVersion { // Version (submitted, accepted, published) private String articleVersion; - // Version label - private String articleVersionLabel; - // Option number private int option; @@ -108,11 +105,4 @@ public class SHERPAPermittedVersion { this.option = option; } - public String getArticleVersionLabel() { - return articleVersionLabel; - } - - public void setArticleVersionLabel(String articleVersionLabel) { - this.articleVersionLabel = articleVersionLabel; - } } From fdabd643f0eb3620612aad6ba08758f3a1629275 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Tue, 3 Nov 2020 13:00:29 +1300 Subject: [PATCH 047/179] [DS-3940] Additional javadoc, integration and unit tests, service refactor --- .../org/dspace/app/sherpa/SHERPAService.java | 322 ++++++++++++++-- .../sherpa/submit/SHERPASubmitService.java | 55 ++- .../app/sherpa/v2/SHERPAPermittedVersion.java | 10 + .../dspace/app/sherpa/v2/SHERPAResponse.java | 66 +++- .../impl/SHERPAv2JournalDataProvider.java | 256 +++---------- .../impl/SHERPAv2JournalISSNDataProvider.java | 193 ++++++++++ .../impl/SHERPAv2PublisherDataProvider.java | 258 ++----------- .../config/spring/api/external-services.xml | 31 ++ .../dspaceFolder/config/spring/api/sherpa.xml | 36 ++ .../spring-dspace-addon-sherpa-services.xml | 35 ++ .../dspace/app/sherpa/MockSHERPAService.java | 135 +++++++ .../app/sherpa/SHERPADataProviderTest.java | 355 ++++++++++++++++++ .../dspace/app/sherpa/SHERPAServiceTest.java | 237 ++++++++++++ .../submit/SHERPASubmitServiceTest.java | 128 +++++++ .../v2/SHERPAPublisherResponseTest.java | 97 ----- .../app/sherpa/v2/SHERPAResponseTest.java | 107 ------ .../org/dspace/app/sherpa/{v2 => }/plos.json | 0 .../dspace/app/sherpa/{v2 => }/thelancet.json | 0 .../config/spring/api/external-services.xml | 24 ++ 19 files changed, 1655 insertions(+), 690 deletions(-) create mode 100644 dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalISSNDataProvider.java create mode 100644 dspace-api/src/test/data/dspaceFolder/config/spring/api/sherpa.xml create mode 100644 dspace-api/src/test/data/dspaceFolder/config/spring/api/spring-dspace-addon-sherpa-services.xml create mode 100644 dspace-api/src/test/java/org/dspace/app/sherpa/MockSHERPAService.java create mode 100644 dspace-api/src/test/java/org/dspace/app/sherpa/SHERPADataProviderTest.java create mode 100644 dspace-api/src/test/java/org/dspace/app/sherpa/SHERPAServiceTest.java create mode 100644 dspace-api/src/test/java/org/dspace/app/sherpa/submit/SHERPASubmitServiceTest.java delete mode 100644 dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java delete mode 100644 dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java rename dspace-api/src/test/resources/org/dspace/app/sherpa/{v2 => }/plos.json (100%) rename dspace-api/src/test/resources/org/dspace/app/sherpa/{v2 => }/thelancet.json (100%) diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java b/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java index 245d372a61..3b9481106f 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/SHERPAService.java @@ -9,6 +9,8 @@ package org.dspace.app.sherpa; import java.io.IOException; import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import org.apache.commons.io.IOUtils; @@ -22,17 +24,31 @@ import org.apache.http.client.utils.URIBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.logging.log4j.Logger; +import org.dspace.app.sherpa.v2.SHERPAPublisherResponse; import org.dspace.app.sherpa.v2.SHERPAResponse; import org.dspace.app.sherpa.v2.SHERPAUtils; import org.dspace.services.ConfigurationService; +import org.dspace.services.factory.DSpaceServicesFactory; import org.springframework.beans.factory.annotation.Autowired; +/** + * SHERPAService is responsible for making the HTTP call to the SHERPA v2 API + * for SHERPASubmitService. + * Note, this service is ported from DSpace 6 for the ability to search policies by ISSN + * There are also new DataProvider implementations provided for use as 'external sources' + * of journal and publisher data + * @see org.dspace.external.provider.impl.SHERPAv2JournalDataProvider + * @see org.dspace.external.provider.impl.SHERPAv2PublisherDataProvider + * @author Kim Shepherd + */ public class SHERPAService { private CloseableHttpClient client = null; private int maxNumberOfTries; private long sleepBetweenTimeouts; private int timeout = 5000; + private String endpoint = "https://v2.sherpa.ac.uk/cgi/retrieve"; + private String apiKey = null; /** log4j category */ private static Logger log = org.apache.logging.log4j.LogManager.getLogger(SHERPAService.class); @@ -40,7 +56,18 @@ public class SHERPAService { @Autowired ConfigurationService configurationService; + /** + * Create a new HTTP builder with sensible defaults in constructor + */ public SHERPAService() { + // Set configuration service + configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); + + // Get endoint and API key from configuration + endpoint = configurationService.getProperty("sherpa.romeo.url", + "https://v2.sherpa.ac.uk/cgi/retrieve"); + apiKey = configurationService.getProperty("sherpa.romeo.apikey"); + HttpClientBuilder builder = HttpClientBuilder.create(); // httpclient 4.3+ doesn't appear to have any sensible defaults any more. Setting conservative defaults as // not to hammer the SHERPA service too much. @@ -50,12 +77,136 @@ public class SHERPAService { .build(); } - + /** + * Search the SHERPA v2 API for a journal policy data using the supplied ISSN. + * If the API key is missing, or the HTTP response is non-OK or does not complete + * successfully, a simple error response will be returned. + * Otherwise, the response body will be passed to SHERPAResponse for parsing as JSON + * and the final result returned to the calling method + * @param query ISSN string to pass in an "issn equals" API query + * @return SHERPAResponse containing an error or journal policies + */ public SHERPAResponse searchByJournalISSN(String query) { - String endpoint = configurationService.getProperty("sherpa.romeo.url", - "https://v2.sherpa.ac.uk/cgi/retrieve"); - String apiKey = configurationService.getProperty("sherpa.romeo.apikey"); + return performRequest("publication", "issn", "equals", query, 0, 1); + } + /** + * Perform an API request to the SHERPA v2 API - this could be a search or a get for any entity type + * but the return object here must be a SHERPAPublisherResponse not the journal-centric SHERPAResponse + * For more information about the type, field and predicate arguments, see the SHERPA v2 API documentation + * @param type entity type eg "publisher" + * @param field field eg "issn" or "title" + * @param predicate predicate eg "equals" or "contains-word" + * @param value the actual value to search for (eg an ISSN or partial title) + * @param start start / offset of search results + * @param limit maximum search results to return + * @return SHERPAPublisherResponse object + */ + public SHERPAPublisherResponse performPublisherRequest(String type, String field, String predicate, String value, + int start, int limit) { + // API Key is *required* for v2 API calls + if (null == apiKey) { + log.error("SHERPA ROMeO API Key missing: please register for an API key and set sherpa.romeo.apikey"); + return new SHERPAPublisherResponse("SHERPA/RoMEO configuration invalid or missing"); + } + + HttpGet method = null; + SHERPAPublisherResponse sherpaResponse = null; + int numberOfTries = 0; + + while (numberOfTries < maxNumberOfTries && sherpaResponse == null) { + numberOfTries++; + + log.debug(String.format( + "Trying to contact SHERPA/RoMEO - attempt %d of %d; timeout is %d; sleep between timeouts is %d", + numberOfTries, + maxNumberOfTries, + timeout, + sleepBetweenTimeouts)); + + try { + Thread.sleep(sleepBetweenTimeouts); + + // Construct a default HTTP method (first result) + method = constructHttpGet(type, field, predicate, value, start, limit); + + // Execute the method + HttpResponse response = client.execute(method); + int statusCode = response.getStatusLine().getStatusCode(); + + log.debug(response.getStatusLine().getStatusCode() + ": " + + response.getStatusLine().getReasonPhrase()); + + if (statusCode != HttpStatus.SC_OK) { + sherpaResponse = new SHERPAPublisherResponse("SHERPA/RoMEO return not OK status: " + + statusCode); + String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); + log.error("Error from SHERPA HTTP request: " + errorBody); + } + + HttpEntity responseBody = response.getEntity(); + + // If the response body is valid, pass to SHERPAResponse for parsing as JSON + if (null != responseBody) { + log.debug("Non-null SHERPA resonse received for query of " + value); + InputStream content = null; + try { + content = responseBody.getContent(); + sherpaResponse = + new SHERPAPublisherResponse(content, SHERPAPublisherResponse.SHERPAFormat.JSON); + } catch (IOException e) { + log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e); + } finally { + if (content != null) { + content.close(); + } + } + } else { + log.debug("Empty SHERPA response body for query on " + value); + sherpaResponse = new SHERPAPublisherResponse("SHERPA/RoMEO returned no response"); + } + } catch (URISyntaxException e) { + String errorMessage = "Error building SHERPA v2 API URI: " + e.getMessage(); + log.error(errorMessage, e); + sherpaResponse = new SHERPAPublisherResponse(errorMessage); + } catch (IOException e) { + String errorMessage = "Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(); + log.error(errorMessage, e); + sherpaResponse = new SHERPAPublisherResponse(errorMessage); + } catch (InterruptedException e) { + String errorMessage = "Encountered exception while sleeping thread: " + e.getMessage(); + log.error(errorMessage, e); + sherpaResponse = new SHERPAPublisherResponse(errorMessage); + } finally { + if (method != null) { + method.releaseConnection(); + } + } + } + + if (sherpaResponse == null) { + log.debug("SHERPA response is still null"); + sherpaResponse = new SHERPAPublisherResponse( + "Error processing the SHERPA/RoMEO answer"); + } + + // Return the final response + return sherpaResponse; + } + + /** + * Perform an API request to the SHERPA v2 API - this could be a search or a get for any entity type + * For more information about the type, field and predicate arguments, see the SHERPA v2 API documentation + * @param type entity type eg "publication" or "publisher" + * @param field field eg "issn" or "title" + * @param predicate predicate eg "equals" or "contains-word" + * @param value the actual value to search for (eg an ISSN or partial title) + * @param start start / offset of search results + * @param limit maximum search results to return + * @return SHERPAResponse object + */ + public SHERPAResponse performRequest(String type, String field, String predicate, String value, + int start, int limit) { // API Key is *required* for v2 API calls if (null == apiKey) { log.error("SHERPA ROMeO API Key missing: please register for an API key and set sherpa.romeo.apikey"); @@ -69,53 +220,38 @@ public class SHERPAService { while (numberOfTries < maxNumberOfTries && sherpaResponse == null) { numberOfTries++; - if (log.isDebugEnabled()) { - log.debug(String.format( - "Trying to contact SHERPA/RoMEO - attempt %d of %d; timeout is %d; sleep between timeouts is %d", - numberOfTries, - maxNumberOfTries, - timeout, - sleepBetweenTimeouts)); - } + log.debug(String.format( + "Trying to contact SHERPA/RoMEO - attempt %d of %d; timeout is %d; sleep between timeouts is %d", + numberOfTries, + maxNumberOfTries, + timeout, + sleepBetweenTimeouts)); try { Thread.sleep(sleepBetweenTimeouts); - // Sanitise query string - query = SHERPAUtils.sanitiseQuery(query); - - URIBuilder uriBuilder = new URIBuilder(endpoint); - - uriBuilder.addParameter("item-type", "publication"); - uriBuilder.addParameter("filter", "[[\"issn\",\"equals\",\"" + query + "\"]]"); - uriBuilder.addParameter("format", "Json"); - if (StringUtils.isNotBlank(apiKey)) { - uriBuilder.addParameter("api-key", apiKey); - } - - log.debug("Searching SHERPA endpoint with " + uriBuilder.toString()); - - method = new HttpGet(uriBuilder.build()); - method.setConfig(RequestConfig.custom() - .setConnectionRequestTimeout(timeout) - .setConnectTimeout(timeout) - .setSocketTimeout(timeout) - .build()); - // Execute the method. + // Construct a default HTTP method (first result) + method = constructHttpGet(type, field, predicate, value, start, limit); + // Execute the method HttpResponse response = client.execute(method); int statusCode = response.getStatusLine().getStatusCode(); + log.debug(response.getStatusLine().getStatusCode() + ": " + + response.getStatusLine().getReasonPhrase()); + if (statusCode != HttpStatus.SC_OK) { sherpaResponse = new SHERPAResponse("SHERPA/RoMEO return not OK status: " - + statusCode); + + statusCode); String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); log.error("Error from SHERPA HTTP request: " + errorBody); } HttpEntity responseBody = response.getEntity(); + // If the response body is valid, pass to SHERPAResponse for parsing as JSON if (null != responseBody) { + log.debug("Non-null SHERPA resonse received for query of " + value); InputStream content = null; try { content = responseBody.getContent(); @@ -128,10 +264,21 @@ public class SHERPAService { } } } else { + log.debug("Empty SHERPA response body for query on " + value); sherpaResponse = new SHERPAResponse("SHERPA/RoMEO returned no response"); } - } catch (Exception e) { - log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e); + } catch (URISyntaxException e) { + String errorMessage = "Error building SHERPA v2 API URI: " + e.getMessage(); + log.error(errorMessage, e); + sherpaResponse = new SHERPAResponse(errorMessage); + } catch (IOException e) { + String errorMessage = "Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(); + log.error(errorMessage, e); + sherpaResponse = new SHERPAResponse(errorMessage); + } catch (InterruptedException e) { + String errorMessage = "Encountered exception while sleeping thread: " + e.getMessage(); + log.error(errorMessage, e); + sherpaResponse = new SHERPAResponse(errorMessage); } finally { if (method != null) { method.releaseConnection(); @@ -140,13 +287,116 @@ public class SHERPAService { } if (sherpaResponse == null) { + log.debug("SHERPA response is still null"); sherpaResponse = new SHERPAResponse( "Error processing the SHERPA/RoMEO answer"); } + // Return the final response return sherpaResponse; } + /** + * Construct HTTP GET object for a "field,predicate,value" query with default start, limit + * eg. "title","contains-word","Lancet" or "issn","equals","1234-1234" + * @param field the field (issn, title, etc) + * @param predicate the predicate (contains-word, equals, etc - see API docs) + * @param value the query value itself + * @return HttpGet method which can then be executed by the client + * @throws URISyntaxException if the URL build fails + */ + public HttpGet constructHttpGet(String type, String field, String predicate, String value) + throws URISyntaxException { + return constructHttpGet(type, field, predicate, value, 0, 1); + } + + /** + * Construct HTTP GET object for a "field,predicate,value" query + * eg. "title","contains-word","Lancet" or "issn","equals","1234-1234" + * @param field the field (issn, title, etc) + * @param predicate the predicate (contains-word, equals, etc - see API docs) + * @param value the query value itself + * @param start row offset + * @param limit number of results to return + * @return HttpGet object to be executed by the client + * @throws URISyntaxException + */ + public HttpGet constructHttpGet(String type, String field, String predicate, String value, int start, int limit) + throws URISyntaxException { + // Sanitise query string (strip some characters) field, predicate and value + if (null == type) { + type = "publication"; + } + field = SHERPAUtils.sanitiseQuery(field); + predicate = SHERPAUtils.sanitiseQuery(predicate); + value = SHERPAUtils.sanitiseQuery(value); + type = SHERPAUtils.sanitiseQuery(type); + + // Build URL based on search query + URIBuilder uriBuilder = new URIBuilder(endpoint); + uriBuilder.addParameter("item-type", type); + uriBuilder.addParameter("filter", "[[\"" + field + "\",\"" + predicate + "\",\"" + value + "\"]]"); + uriBuilder.addParameter("format", "Json"); + // Set optional start (offset) and limit parameters + if (start >= 0) { + uriBuilder.addParameter("offset", String.valueOf(start)); + } + if (limit > 0) { + uriBuilder.addParameter("limit", String.valueOf(limit)); + } + if (StringUtils.isNotBlank(apiKey)) { + uriBuilder.addParameter("api-key", apiKey); + } + + log.debug("SHERPA API URL: " + uriBuilder.toString()); + + // Create HTTP GET object + HttpGet method = new HttpGet(uriBuilder.build()); + + // Set connection parameters + int timeout = 5000; + method.setConfig(RequestConfig.custom() + .setConnectionRequestTimeout(timeout) + .setConnectTimeout(timeout) + .setSocketTimeout(timeout) + .build()); + + return method; + } + + /** + * Prepare the API query for execution by the HTTP client + * @param query ISSN query string + * @param endpoint API endpoint (base URL) + * @param apiKey API key parameter + * @return URI object + * @throws URISyntaxException + */ + public URI prepareQuery(String query, String endpoint, String apiKey) throws URISyntaxException { + // Sanitise query string + query = SHERPAUtils.sanitiseQuery(query); + + // Instantiate URI builder + URIBuilder uriBuilder = new URIBuilder(endpoint); + + // Build URI parameters from supplied values + uriBuilder.addParameter("item-type", "publication"); + + // Log warning if no query is supplied + if (null == query) { + log.warn("No ISSN supplied as query string for SHERPA service search"); + } + uriBuilder.addParameter("filter", "[[\"issn\",\"equals\",\"" + query + "\"]]"); + uriBuilder.addParameter("format", "Json"); + if (StringUtils.isNotBlank(apiKey)) { + uriBuilder.addParameter("api-key", apiKey); + } + log.debug("Would search SHERPA endpoint with " + uriBuilder.toString()); + + // Return final built URI + return uriBuilder.build(); + } + public void setMaxNumberOfTries(int maxNumberOfTries) { this.maxNumberOfTries = maxNumberOfTries; } diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/submit/SHERPASubmitService.java b/dspace-api/src/main/java/org/dspace/app/sherpa/submit/SHERPASubmitService.java index 1f0dbcefb1..fdf5b3c167 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/submit/SHERPASubmitService.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/submit/SHERPASubmitService.java @@ -20,24 +20,54 @@ import org.dspace.content.Item; import org.dspace.core.Context; import org.dspace.core.LogManager; +/** + * SHERPASubmitService is + * @see + * @author Kim Shepherd + */ public class SHERPASubmitService { - private SHERPAService sherpaService; - private SHERPASubmitConfigurationService configuration; + /** + * Spring beans for configuration and API service + */ + protected SHERPAService sherpaService; + protected SHERPASubmitConfigurationService configuration; /** * log4j logger */ private static Logger log = org.apache.logging.log4j.LogManager.getLogger(SHERPASubmitService.class); + /** + * Setter for configuration (from Spring) + * @see "dspace-dspace-addon-sherpa-configuration-services.xml" + * @param configuration + */ public void setConfiguration(SHERPASubmitConfigurationService configuration) { this.configuration = configuration; } + /** + * Setter for SHERPA service, reponsible for actual HTTP API calls + * @see "dspace-dspace-addon-sherpa-configuration-services.xml" + * @param sherpaService + */ public void setSherpaService(SHERPAService sherpaService) { this.sherpaService = sherpaService; } + /** + * Search SHERPA for journal policies matching the ISSNs in the item. + * Rather than a 'search' query for any/all ISSNs, the v2 API requires a separate + * query for each ISSN found in the item. The ISSNs are extracted using the configured + * issnItemExtractor(s) in the SHERPA spring configuration. + * The ISSNs are not validated with a regular expression or other rules - any values + * extracted will be included in API queries. + * @see "dspace-dspace-addon-sherpa-configuration-services.xml" + * @param context DSpace context + * @param item DSpace item containing ISSNs to be checked + * @return SHERPA v2 API response (policy data) + */ public List searchRelatedJournals(Context context, Item item) { Set issns = getISSNs(context, item); if (issns == null || issns.size() == 0) { @@ -64,10 +94,24 @@ public class SHERPASubmitService { } } + /** + * Search SHERPA for journal policies matching the passed ISSN. + * The ISSN are not validated with a regular expression or other rules - any String + * passed to this method will be considered an ISSN for the purposes of an API query + * @param issn ISSN string + * @return SHERPA v2 API response object (policy data) + */ public SHERPAResponse searchRelatedJournalsByISSN(String issn) { return sherpaService.searchByJournalISSN(issn); } + /** + * Using the configured itemIssnExtractors from SHERPA configuration, extract + * ISSNs from item metadata or authority values + * @param context DSpace context + * @param item Item containing metadata / authority values + * @return Set of ISSN strings + */ public Set getISSNs(Context context, Item item) { Set issns = new LinkedHashSet(); if (configuration.getIssnItemExtractors() == null) { @@ -86,6 +130,13 @@ public class SHERPASubmitService { return issns; } + /** + * Simple boolean test that runs the getISSNs extraction method + * to determine whether an item has any ISSNs at all + * @param context DSpace context + * @param item Item to test + * @return boolean indicating presence of >=1 ISSNs + */ public boolean hasISSNs(Context context, Item item) { Set issns = getISSNs(context, item); if (issns == null || issns.size() == 0) { diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java index ec45a29ce7..dca04b2bb9 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAPermittedVersion.java @@ -30,6 +30,9 @@ public class SHERPAPermittedVersion { // Version (submitted, accepted, published) private String articleVersion; + // Version label + private String articleVersionLabel; + // Option number private int option; @@ -105,4 +108,11 @@ public class SHERPAPermittedVersion { this.option = option; } + public String getArticleVersionLabel() { + return articleVersionLabel; + } + + public void setArticleVersionLabel(String articleVersionLabel) { + this.articleVersionLabel = articleVersionLabel; + } } diff --git a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java index 9bb1c89a23..08bf8e8662 100644 --- a/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java +++ b/dspace-api/src/main/java/org/dspace/app/sherpa/v2/SHERPAResponse.java @@ -17,6 +17,7 @@ import java.util.Map; import java.util.TreeMap; import org.apache.log4j.Logger; +import org.dspace.core.I18nUtil; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -264,6 +265,7 @@ public class SHERPAResponse { + titleList.get(0)); sherpaJournal.setZetoPub(publisherName + ": " + titleList.get(0)); + log.debug("Found journal title: " + titleList.get(0)); } } } @@ -333,25 +335,39 @@ public class SHERPAResponse { JSONArray permittedOA = policy.getJSONArray("permitted_oa"); List permittedVersions = new ArrayList<>(); - // Iterate each permitted OA version / option + // Iterate each permitted OA version / option. The permitted_oa node is also known as a 'pathway' -- + // essentially "a way to get a work into a repository". Each pathway could refer to one article version + // like a pre-print, or multiple versions might have the same acceptable locations and conditions. + // As described below, where multiple versions are referenced in a single permitted_oa pathway, they will + // be split out and treated separately. This keeps processing simple, especially later in display or + // compliance checking when it is preferred to group / indicate rules by the article version for (int p = 0; p < permittedOA.length(); p++) { JSONObject permitted = permittedOA.getJSONObject(p); - SHERPAPermittedVersion permittedVersion = parsePermittedVersion(permitted); + // Although it adds redundancy, we will treat each 'article version' within + // the permitted_oa ("pathway") node as a separate version altogether to keep the rest of our display + // handled nicely. This was confirmed as an appropriate approach by JISC + if (permitted.has("article_version")) { + JSONArray versions = permitted.getJSONArray("article_version"); + for (int v = 0; v < versions.length(); v++) { + // Parse this permitted_oa node but specifically looking for the article_version 'v' + SHERPAPermittedVersion permittedVersion = parsePermittedVersion(permitted, v); - // To determine which option # we are, inspect article versions and set - allowed.add(permittedVersion.getArticleVersion()); - if ("submitted".equals(permittedVersion.getArticleVersion())) { - submittedOption++; - currentOption = submittedOption; - } else if ("accepted".equals(permittedVersion.getArticleVersion())) { - acceptedOption++; - currentOption = acceptedOption; - } else if ("published".equals(permittedVersion.getArticleVersion())) { - publishedOption++; - currentOption = publishedOption; + // To determine which option # we are, inspect article versions and set + allowed.add(permittedVersion.getArticleVersion()); + if ("submitted".equals(permittedVersion.getArticleVersion())) { + submittedOption++; + currentOption = submittedOption; + } else if ("accepted".equals(permittedVersion.getArticleVersion())) { + acceptedOption++; + currentOption = acceptedOption; + } else if ("published".equals(permittedVersion.getArticleVersion())) { + publishedOption++; + currentOption = publishedOption; + } + permittedVersion.setOption(currentOption); + permittedVersions.add(permittedVersion); + } } - permittedVersion.setOption(currentOption); - permittedVersions.add(permittedVersion); // Populate the old indicators into the publisher policy object if (allowed.contains("submitted")) { @@ -376,7 +392,7 @@ public class SHERPAResponse { * @param permitted - each 'permitted_oa' node in the JSON array * @return populated SHERPAPermittedVersion object */ - private SHERPAPermittedVersion parsePermittedVersion(JSONObject permitted) { + private SHERPAPermittedVersion parsePermittedVersion(JSONObject permitted, int index) { SHERPAPermittedVersion permittedVersion = new SHERPAPermittedVersion(); @@ -387,14 +403,30 @@ public class SHERPAResponse { // published = pdfversion // These strings can be used to construct i18n messages. String articleVersion = "unknown"; + String versionLabel = "Unknown"; + // Each 'permitted OA' can actually refer to multiple versions if (permitted.has("article_version")) { JSONArray versions = permitted.getJSONArray("article_version"); - articleVersion = versions.getString(0); + + // Get one particular article version to return as a PermittedVersion. The outer loop calling this + // is iterating all permitted_oa and permitted_oa->article_version array members + articleVersion = versions.getString(index); permittedVersion.setArticleVersion(articleVersion); log.debug("Added allowed version: " + articleVersion + " to list"); } + // Add labels for this particular article version + if ("submitted".equals(articleVersion)) { + versionLabel = I18nUtil.getMessage("jsp.sherpa.submitted-version-label"); + } else if ("accepted".equals(articleVersion)) { + versionLabel = I18nUtil.getMessage("jsp.sherpa.accepted-version-label"); + } else if ("published".equals(articleVersion)) { + versionLabel = I18nUtil.getMessage("jsp.sherpa.published-version-label"); + } + // Set the article version label based on the i18n text set above + permittedVersion.setArticleVersionLabel(versionLabel); + // These are now child arrays, in old API they were explicit like // "preprint restrictions", etc., and just contained text rather than data if (permitted.has("conditions")) { diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java index 4fbdbf5aa0..10df1790bd 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java @@ -8,35 +8,22 @@ package org.dspace.external.provider.impl; import java.io.IOException; -import java.io.InputStream; -import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; import org.apache.logging.log4j.Logger; +import org.dspace.app.sherpa.SHERPAService; import org.dspace.app.sherpa.v2.SHERPAJournal; import org.dspace.app.sherpa.v2.SHERPAResponse; import org.dspace.app.sherpa.v2.SHERPAUtils; import org.dspace.content.dto.MetadataValueDTO; import org.dspace.external.model.ExternalDataObject; import org.dspace.external.provider.ExternalDataProvider; -import org.dspace.services.factory.DSpaceServicesFactory; /** * This class is the implementation of the ExternalDataProvider interface that will deal with SherpaJournal External @@ -49,11 +36,11 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(SHERPAv2JournalDataProvider.class); - private String url; + // Source identifier (configured in spring configuration) private String sourceIdentifier; - private String apiKey; - private CloseableHttpClient client = null; + // SHERPA v2 API service (configured in spring configuration) + SHERPAService sherpaService; @Override public String getSourceIdentifier() { @@ -64,20 +51,7 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { * Initialise the client that we need to call the endpoint * @throws IOException If something goes wrong */ - public void init() throws IOException { - HttpClientBuilder builder = HttpClientBuilder.create(); - // httpclient 4.3+ doesn't appear to have any sensible defaults any more. Setting conservative defaults as - // not to hammer the SHERPA service too much. - client = builder - .disableAutomaticRetries() - .setMaxConnTotal(5) - .build(); - - // Initialise API key and base URL from configuration service - apiKey = DSpaceServicesFactory.getInstance().getConfigurationService().getProperty("sherpa.romeo.apikey"); - url = DSpaceServicesFactory.getInstance().getConfigurationService().getProperty("sherpa.romeo.url", - "https://v2.sherpa.ac.uk/cgi/retrieve"); - } + public void init() throws IOException {} /** * Get a single journal based on a "title equals string" query @@ -86,76 +60,22 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { */ @Override public Optional getExternalDataObject(String id) { - - HttpGet method = null; - SHERPAResponse sherpaResponse = null; - int timeout = 5000; - URIBuilder uriBuilder = null; - // Sanitise ID / title query string (strips some special characters) id = SHERPAUtils.sanitiseQuery(id); - try { - // Construct URI for an exact match on journal title - uriBuilder = new URIBuilder(url); - uriBuilder.addParameter("item-type", "publication"); - uriBuilder.addParameter("filter", "[[\"title\",\"equals\",\"" + id + "\"]]"); - uriBuilder.addParameter("format", "Json"); - if (StringUtils.isNotBlank(apiKey)) { - uriBuilder.addParameter("api-key", apiKey); - } + // Perform request using the SHERPA service (first row only) + SHERPAResponse sherpaResponse = sherpaService.performRequest("publication", "title", "equals", id, + 0, 1); - // Build HTTP method - method = new HttpGet(uriBuilder.build()); - method.setConfig(RequestConfig.custom() - .setConnectionRequestTimeout(timeout) - .setConnectTimeout(timeout) - .setSocketTimeout(timeout) - .build()); - - // Execute the method - HttpResponse response = client.execute(method); - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode != HttpStatus.SC_OK) { - sherpaResponse = new SHERPAResponse("SHERPA/RoMEO return not OK status: " - + statusCode); - String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); - log.error("Error from SHERPA HTTP request: " + errorBody); - } - - HttpEntity responseBody = response.getEntity(); - - // Get InputStream from API response and parse JSON - if (null != responseBody) { - InputStream content = null; - try { - content = responseBody.getContent(); - sherpaResponse = new SHERPAResponse(content, SHERPAResponse.SHERPAFormat.JSON); - } catch (IOException e) { - log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e); - } finally { - if (content != null) { - content.close(); - } - } - } else { - sherpaResponse = new SHERPAResponse("SHERPA/RoMEO returned no response"); - } - } catch (Exception e) { - log.error("SHERPA/RoMEO query failed: ", e); - } - - if (sherpaResponse == null) { - sherpaResponse = new SHERPAResponse( - "Error processing the SHERPA/RoMEO answer"); - } + // If a journal was returned, get it and convert it to an ExternalDataObject if (CollectionUtils.isNotEmpty(sherpaResponse.getJournals())) { SHERPAJournal sherpaJournal = sherpaResponse.getJournals().get(0); ExternalDataObject externalDataObject = constructExternalDataObjectFromSherpaJournal(sherpaJournal); return Optional.of(externalDataObject); } + + // If no journal was returned, return an empty Optional object return Optional.empty(); } @@ -197,101 +117,25 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { */ @Override public List searchExternalDataObjects(String query, int start, int limit) { - // query args to add to SHERPA/RoMEO request URL - HttpGet get = null; - try { - get = constructHttpGet(query, start, limit); - HttpClient hc = new DefaultHttpClient(); - HttpResponse response = hc.execute(get); - if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { - // Get response input stream and parse JSON into new SHERPAResponse object - InputStream content = null; - try { - content = response.getEntity().getContent(); - SHERPAResponse sherpaResponse = new SHERPAResponse(content, SHERPAResponse.SHERPAFormat.JSON); - if (CollectionUtils.isNotEmpty(sherpaResponse.getJournals())) { - List list = sherpaResponse.getJournals().stream().map( - sherpaJournal -> constructExternalDataObjectFromSherpaJournal(sherpaJournal)).collect( - Collectors.toList()); + // Search SHERPA for journals with the query term in the title + SHERPAResponse sherpaResponse = sherpaService.performRequest("publication", "title", + "contains word", query, start, limit); - // Unlike the previous API version we can request offset and limit, so no need to build a - // sublist from this list, we can just return the list. - return list; - } - } catch (IOException e) { - log.error("Error parsing SHERPA response input stream: " + e.getMessage()); - throw new IOException(e); - } finally { - if (content != null) { - content.close(); - } - } - } else { - String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); - log.error("Error from SHERPA HTTP request: " + errorBody); - } - } catch (IOException | URISyntaxException e) { - log.error("SHERPA/RoMEO query failed: ", e); - return null; - } finally { - if (get != null) { - get.releaseConnection(); - } + // Convert SHERPA response to a Collection and return the list + if (CollectionUtils.isNotEmpty(sherpaResponse.getJournals())) { + List list = sherpaResponse.getJournals().stream().map( + sherpaJournal -> constructExternalDataObjectFromSherpaJournal(sherpaJournal)).collect( + Collectors.toList()); + + // Unlike the previous API version we can request offset and limit, so no need to build a + // sublist from this list, we can just return the list. + return list; } + + // If nothing has been returned yet, return an empty list return Collections.emptyList(); } - /** - * Construct HTTP GET object for a "title contains word" query using default start/limit parameters - * @param query a word or phrase to search for in journal title - * @return HttpGet method which can then be executed by the client - * @throws URISyntaxException if the URL build fails - */ - private HttpGet constructHttpGet(String query) throws URISyntaxException { - return constructHttpGet(query, -1, -1); - } - - /** - * Construct HTTP GET object for a "title contains word" query - * @param query the search query - * @param start row offset - * @param limit number of results to return - * @return HttpGet object to be executed by the client - * @throws URISyntaxException - */ - private HttpGet constructHttpGet(String query, int start, int limit) throws URISyntaxException { - // Sanitise query string (strip some characters) - query = SHERPAUtils.sanitiseQuery(query); - - // Build URL based on search query - URIBuilder uriBuilder = new URIBuilder(url); - uriBuilder.addParameter("item-type", "publication"); - uriBuilder.addParameter("filter", "[[\"title\",\"contains word\",\"" + query + "\"]]"); - uriBuilder.addParameter("format", "Json"); - // Set optional start (offset) and limit parameters - if (start >= 0) { - uriBuilder.addParameter("offset", String.valueOf(start)); - } - if (limit > 0) { - uriBuilder.addParameter("limit", String.valueOf(limit)); - } - if (StringUtils.isNotBlank(apiKey)) { - uriBuilder.addParameter("api-key", apiKey); - } - - // Create HTTP GET object - HttpGet method = new HttpGet(uriBuilder.build()); - - // Set connection parameters - int timeout = 5000; - method.setConfig(RequestConfig.custom() - .setConnectionRequestTimeout(timeout) - .setConnectTimeout(timeout) - .setSocketTimeout(timeout) - .build()); - return new HttpGet(uriBuilder.build()); - } - @Override public boolean supports(String source) { return StringUtils.equalsIgnoreCase(sourceIdentifier, source); @@ -304,40 +148,16 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { */ @Override public int getNumberOfResults(String query) { - HttpGet get = null; - try { - get = constructHttpGet(query); - HttpClient hc = new DefaultHttpClient(); - HttpResponse response = hc.execute(get); - if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { - // Read response and parse as SHERPAResponse object - InputStream content = null; - try { - content = response.getEntity().getContent(); - SHERPAResponse sherpaResponse = new SHERPAResponse(content, SHERPAResponse.SHERPAFormat.JSON); - if (CollectionUtils.isNotEmpty(sherpaResponse.getJournals())) { - return sherpaResponse.getJournals().size(); - } - } catch (IOException e) { - log.error("Error reading input stream for SHERPAResponse: " + e.getMessage()); - throw new IOException(e); - } finally { - if (content != null) { - content.close(); - } - } - } else { - String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); - log.error("Error from SHERPA HTTP request: " + errorBody); - } - } catch (IOException | URISyntaxException e) { - log.error("SHERPA/RoMEO query failed: ", e); - return 0; - } finally { - if (get != null) { - get.releaseConnection(); - } + // Search SHERPA for journals with the query term in the title + // Limit = 0 means the limit parameter will not be added to the API query + SHERPAResponse sherpaResponse = sherpaService.performRequest("publication", "title", + "contains word", query, 0, 0); + + // Get number of journals returned in response + if (CollectionUtils.isNotEmpty(sherpaResponse.getJournals())) { + return sherpaResponse.getJournals().size(); } + // If other checks have failed return 0 return 0; } @@ -350,4 +170,12 @@ public class SHERPAv2JournalDataProvider implements ExternalDataProvider { this.sourceIdentifier = sourceIdentifier; } + /** + * Generic setter for the SHERPA service + * @param sherpaService The sherpaService to be set on this SHERPAv2JournalDataProvider + */ + public void setSherpaService(SHERPAService sherpaService) { + this.sherpaService = sherpaService; + } + } diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalISSNDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalISSNDataProvider.java new file mode 100644 index 0000000000..ed2df53c83 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalISSNDataProvider.java @@ -0,0 +1,193 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.external.provider.impl; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.Logger; +import org.dspace.app.sherpa.SHERPAService; +import org.dspace.app.sherpa.v2.SHERPAJournal; +import org.dspace.app.sherpa.v2.SHERPAResponse; +import org.dspace.app.sherpa.v2.SHERPAUtils; +import org.dspace.content.dto.MetadataValueDTO; +import org.dspace.external.model.ExternalDataObject; +import org.dspace.external.provider.ExternalDataProvider; + +/** + * This class is the implementation of the ExternalDataProvider interface that will deal with SherpaJournal External + * data lookups based on ISSN (to match functinoality offered by legacy SHERPASubmitService for policy lookups + * at the time of submission). + * This provider is a refactored version of SherpaJournalDataPublisher, rewritten to work with SHERPA v2 API + * + * @author Kim Shepherd + */ +public class SHERPAv2JournalISSNDataProvider implements ExternalDataProvider { + + private static final Logger log = + org.apache.logging.log4j.LogManager.getLogger( + org.dspace.external.provider.impl.SHERPAv2JournalISSNDataProvider.class); + + // Source identifier (configured in spring configuration) + private String sourceIdentifier; + + // SHERPA v2 API service (configured in spring configuration) + SHERPAService sherpaService; + + @Override + public String getSourceIdentifier() { + return sourceIdentifier; + } + + /** + * Initialise the provider - this no longer starts client since that is handled by SHERPAService + * @throws IOException If something goes wrong + */ + public void init() throws IOException { + } + + /** + * Get a single journal based on a "issn equals string" query + * @param issn The ISSN which will be used as query string + * @return external data object representing journal + */ + @Override + public Optional getExternalDataObject(String issn) { + + // Sanitise ID / title query string (strips some special characters) + issn = SHERPAUtils.sanitiseQuery(issn); + + log.debug("Searching SHERPA for ISSN: " + issn); + + // Get SHERPA response from base service + // Get SHERPA response from the API for all objects matching this ISSN + SHERPAResponse sherpaResponse = sherpaService.performRequest( + "publication", "issn", "equals", issn, 0, 1); + + // Construct external data objects + if (CollectionUtils.isNotEmpty(sherpaResponse.getJournals())) { + SHERPAJournal sherpaJournal = sherpaResponse.getJournals().get(0); + ExternalDataObject externalDataObject = constructExternalDataObjectFromSherpaJournal(sherpaJournal); + return Optional.of(externalDataObject); + } + return Optional.empty(); + } + + /** + * Construct ExternalDataObject populated with journal metadata from the SHERPA v2 API response + * @param sherpaJournal + * @return external data object representing a journal + */ + private ExternalDataObject constructExternalDataObjectFromSherpaJournal(SHERPAJournal sherpaJournal) { + // Set up external object + ExternalDataObject externalDataObject = new ExternalDataObject(); + externalDataObject.setSource(sourceIdentifier); + // Set journal title in external object + if (CollectionUtils.isNotEmpty(sherpaJournal.getTitles())) { + String journalTitle = sherpaJournal.getTitles().get(0); + externalDataObject.setId(sherpaJournal.getTitles().get(0)); + externalDataObject.addMetadata(new MetadataValueDTO( + "dc", "title", null, null, journalTitle)); + externalDataObject.setValue(journalTitle); + externalDataObject.setDisplayValue(journalTitle); + } + // Set ISSNs in external object + if (CollectionUtils.isNotEmpty(sherpaJournal.getIssns())) { + String issn = sherpaJournal.getIssns().get(0); + externalDataObject.setId(issn); + externalDataObject.addMetadata(new MetadataValueDTO( + "dc", "identifier", "issn", null, issn)); + + } + + log.debug("New external data object. Title=" + externalDataObject.getValue() + ". ID=" + + externalDataObject.getId()); + + return externalDataObject; + } + + /** + * Search SHERPA v2 API for journal results based on a 'contains word' query + * @param query The term to query for the search + * @param start The start of the search + * @param limit The max amount of records to be returned by the search + * @return a list of external data objects + */ + @Override + public List searchExternalDataObjects(String query, int start, int limit) { + + // Get SHERPA response from the API for all objects matching this ISSN + SHERPAResponse sherpaResponse = sherpaService.performRequest( + "publication", "issn", "equals", query, start, limit); + + // Construct a list of external data objects and return it + if (CollectionUtils.isNotEmpty(sherpaResponse.getJournals())) { + log.debug("Found " + sherpaResponse.getJournals().size() + " matching journals for ISSN " + query); + List list = sherpaResponse.getJournals().stream().map( + sherpaJournal -> constructExternalDataObjectFromSherpaJournal(sherpaJournal)).collect( + Collectors.toList()); + + // Unlike the previous API version we can request offset and limit, so no need to build aF + // sublist from this list, we can just return the list. + return list; + } else { + log.debug("Empty response from SHERPA v2 API for ISSN " + query); + } + + // If nothing was returned from the response, return an empty list + return Collections.emptyList(); + } + + @Override + public boolean supports(String source) { + return StringUtils.equalsIgnoreCase(sourceIdentifier, source); + } + + /** + * Get number of results returned from a SHERPA v2 publication search + * @param issn The query to be search on and give the total amount of results + * @return int representing number of journal results + */ + @Override + public int getNumberOfResults(String issn) { + + // Get SHERPA response from the API for all objects matching this ISSN. + // The limit of 0 means a limit parameter will not be added to the API query + SHERPAResponse sherpaResponse = sherpaService.performRequest( + "publication", "issn", "equals", issn, 0, 0); + + // Return the size of the journal collection + if (CollectionUtils.isNotEmpty(sherpaResponse.getJournals())) { + return sherpaResponse.getJournals().size(); + } + + // If other checks have failed return 0 + return 0; + } + + /** + * Generic setter for the sourceIdentifier + * @param sourceIdentifier The sourceIdentifier to be set on this SHERPAv2JournalISSNDataProvider + */ + public void setSourceIdentifier(String sourceIdentifier) { + this.sourceIdentifier = sourceIdentifier; + } + + /** + * Generic setter for the SHERPA Service + * @param sherpaService THe SHERPA service to be set on this SHERPAv2JournalISSNDataProvider + */ + public void setSherpaService(SHERPAService sherpaService) { + this.sherpaService = sherpaService; + } +} diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java index 905a1caa67..3123689020 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2PublisherDataProvider.java @@ -8,35 +8,21 @@ package org.dspace.external.provider.impl; import java.io.IOException; -import java.io.InputStream; -import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; import org.apache.logging.log4j.Logger; +import org.dspace.app.sherpa.SHERPAService; import org.dspace.app.sherpa.v2.SHERPAPublisher; import org.dspace.app.sherpa.v2.SHERPAPublisherResponse; import org.dspace.app.sherpa.v2.SHERPAUtils; import org.dspace.content.dto.MetadataValueDTO; import org.dspace.external.model.ExternalDataObject; import org.dspace.external.provider.ExternalDataProvider; -import org.dspace.services.factory.DSpaceServicesFactory; /** * This class is the implementation of the ExternalDataProvider interface that will deal with SHERPAPublisher External @@ -49,14 +35,14 @@ import org.dspace.services.factory.DSpaceServicesFactory; */ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { + // Logger private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(SHERPAv2PublisherDataProvider.class); + // Source identifier (eg 'sherpaPublisher') configured in spring configuration private String sourceIdentifier; - private String url; - private String apiKey; - - private CloseableHttpClient client = null; + // SHERPA service configured in spring configuration + private SHERPAService sherpaService; @Override public String getSourceIdentifier() { @@ -67,20 +53,7 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { * Initialise the client that we need to call the endpoint * @throws IOException If something goes wrong */ - public void init() throws IOException { - HttpClientBuilder builder = HttpClientBuilder.create(); - // httpclient 4.3+ doesn't appear to have any sensible defaults any more. Setting conservative defaults as - // not to hammer the SHERPA service too much. - client = builder - .disableAutomaticRetries() - .setMaxConnTotal(5) - .build(); - - // Initialise API key and base URL from configuration service - apiKey = DSpaceServicesFactory.getInstance().getConfigurationService().getProperty("sherpa.romeo.apikey"); - url = DSpaceServicesFactory.getInstance().getConfigurationService().getProperty("sherpa.romeo.url", - "https://v2.sherpa.ac.uk/cgi/retrieve"); - } + public void init() throws IOException {} /** * Get a single publisher based on a "id equals string" query @@ -89,69 +62,14 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { */ @Override public Optional getExternalDataObject(String id) { - - HttpGet method = null; - SHERPAPublisherResponse sherpaResponse = null; - int timeout = 5000; - URIBuilder uriBuilder = null; - // Sanitise the given ID / title query id = SHERPAUtils.sanitiseQuery(id); - try { - // Construct URI for an exact match on journal title - uriBuilder = new URIBuilder(url); - uriBuilder.addParameter("item-type", "publisher"); - uriBuilder.addParameter("filter", "[[\"id\",\"equals\",\"" + id + "\"]]"); - uriBuilder.addParameter("format", "Json"); - if (StringUtils.isNotBlank(apiKey)) { - uriBuilder.addParameter("api-key", apiKey); - } + // Search for publishers matching this ID in SHERPA. Limit to 1 result since this is for a single object + SHERPAPublisherResponse sherpaResponse = + sherpaService.performPublisherRequest("publisher", "id", "equals", id, 0, 1); - // Build HTTP method - method = new HttpGet(uriBuilder.build()); - method.setConfig(RequestConfig.custom() - .setConnectionRequestTimeout(timeout) - .setConnectTimeout(timeout) - .setSocketTimeout(timeout) - .build()); - - // Execute the method - HttpResponse response = client.execute(method); - int statusCode = response.getStatusLine().getStatusCode(); - - if (statusCode != HttpStatus.SC_OK) { - sherpaResponse = new SHERPAPublisherResponse("SHERPA/RoMEO return not OK status: " - + statusCode); - String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); - log.error("Error from SHERPA HTTP request: " + errorBody); - } - - HttpEntity responseBody = response.getEntity(); - - // Get InputStream from API response and parse JSON - if (null != responseBody) { - InputStream content = null; - try { - content = responseBody.getContent(); - sherpaResponse = new SHERPAPublisherResponse(content, SHERPAPublisherResponse.SHERPAFormat.JSON); - } catch (IOException e) { - log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e); - } finally { - if (content != null) { - content.close(); - } - } - } else { - sherpaResponse = new SHERPAPublisherResponse("SHERPA/RoMEO returned no response"); - } - } catch (Exception e) { - log.error("SHERPA/RoMEO query failed: ", e); - } - - if (sherpaResponse == null) { - sherpaResponse = new SHERPAPublisherResponse("Error processing the SHERPA/RoMEO answer"); - } + // If there is at least one publisher, retrieve it and transform it to an ExternalDataObject if (CollectionUtils.isNotEmpty(sherpaResponse.getPublishers())) { SHERPAPublisher sherpaPublisher = sherpaResponse.getPublishers().get(0); // Construct external data object from returned publisher @@ -170,102 +88,25 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { */ @Override public List searchExternalDataObjects(String query, int start, int limit) { - // query args to add to SHERPA/RoMEO request URL - HttpGet get = null; - try { - get = constructHttpGet(query, start, limit); - HttpClient hc = new DefaultHttpClient(); - HttpResponse response = hc.execute(get); - if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { - // Get response input stream and parse JSON into new SHERPAResponse object - InputStream content = null; - try { - content = response.getEntity().getContent(); - SHERPAPublisherResponse sherpaResponse = - new SHERPAPublisherResponse(content, SHERPAPublisherResponse.SHERPAFormat.JSON); - if (CollectionUtils.isNotEmpty(sherpaResponse.getPublishers())) { - List list = sherpaResponse.getPublishers().stream().map( - sherpaPublisher -> constructExternalDataObjectFromSherpaPublisher(sherpaPublisher)).collect( - Collectors.toList()); + // Search SHERPA for publishers with the query term in the title (name) + SHERPAPublisherResponse sherpaResponse = sherpaService.performPublisherRequest( + "publication", "title", "contains word", query, start, limit); - // Unlike the previous API version we can request offset and limit, so no need to build a - // sublist from this list, we can just return the list. - return list; - } - } catch (IOException e) { - log.error("Error parsing SHERPA response input stream: " + e.getMessage()); - throw new IOException(e); - } finally { - if (content != null) { - content.close(); - } - } - } else { - String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); - log.error("Error from SHERPA HTTP request: " + errorBody); - } - } catch (IOException | URISyntaxException e) { - log.error("SHERPA/RoMEO query failed: ", e); - return null; - } finally { - if (get != null) { - get.releaseConnection(); - } + // If at least one publisher was found, convert to a list of ExternalDataObjects and return + if (CollectionUtils.isNotEmpty(sherpaResponse.getPublishers())) { + List list = sherpaResponse.getPublishers().stream().map( + sherpaPublisher -> constructExternalDataObjectFromSherpaPublisher(sherpaPublisher)).collect( + Collectors.toList()); + + // Unlike the previous API version we can request offset and limit, so no need to build a + // sublist from this list, we can just return the list. + return list; } + + // Return an empty list if nothing was found return Collections.emptyList(); } - /** - * Construct HTTP GET object for a "publisher name contains word" query using default start/limit parameters - * @param query a word or phrase to search for in publisher name - * @return HttpGet method which can then be executed by the client - * @throws URISyntaxException if the URL build fails - */ - private HttpGet constructHttpGet(String query) throws URISyntaxException { - return constructHttpGet(query, -1, -1); - } - - /** - * Construct HTTP GET object for a "publisher name contains word" query - * @param query the search query - * @param start row offset - * @param limit number of results to return - * @return HttpGet object to be executed by the client - * @throws URISyntaxException - */ - private HttpGet constructHttpGet(String query, int start, int limit) throws URISyntaxException { - // Sanitise the query string - query = SHERPAUtils.sanitiseQuery(query); - - // Build URL based on search query - URIBuilder uriBuilder = new URIBuilder(url); - uriBuilder.addParameter("item-type", "publisher"); - uriBuilder.addParameter("filter", "[[\"name\",\"contains word\",\"" + query + "\"]]"); - uriBuilder.addParameter("format", "Json"); - // Set optional start (offset) and limit parameters - if (start >= 0) { - uriBuilder.addParameter("offset", String.valueOf(start)); - } - if (limit > 0) { - uriBuilder.addParameter("limit", String.valueOf(limit)); - } - if (StringUtils.isNotBlank(apiKey)) { - uriBuilder.addParameter("api-key", apiKey); - } - - // Create HTTP GET object - HttpGet method = new HttpGet(uriBuilder.build()); - - // Set connection parameters - int timeout = 5000; - method.setConfig(RequestConfig.custom() - .setConnectionRequestTimeout(timeout) - .setConnectTimeout(timeout) - .setSocketTimeout(timeout) - .build()); - return new HttpGet(uriBuilder.build()); - } - private ExternalDataObject constructExternalDataObjectFromSherpaPublisher(SHERPAPublisher sherpaPublisher) { ExternalDataObject externalDataObject = new ExternalDataObject(); externalDataObject.setSource(sourceIdentifier); @@ -306,41 +147,16 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { */ @Override public int getNumberOfResults(String query) { - HttpGet get = null; - try { - get = constructHttpGet(query); - HttpClient hc = new DefaultHttpClient(); - HttpResponse response = hc.execute(get); - if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { - // Read response and parse as SHERPAResponse object - InputStream content = null; - try { - content = response.getEntity().getContent(); - SHERPAPublisherResponse sherpaResponse = - new SHERPAPublisherResponse(content, SHERPAPublisherResponse.SHERPAFormat.JSON); - if (CollectionUtils.isNotEmpty(sherpaResponse.getPublishers())) { - return sherpaResponse.getPublishers().size(); - } - } catch (IOException e) { - log.error("Error reading input stream for SHERPAResponse: " + e.getMessage()); - throw new IOException(e); - } finally { - if (content != null) { - content.close(); - } - } - } else { - String errorBody = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); - log.error("Error from SHERPA HTTP request: " + errorBody); - } - } catch (IOException | URISyntaxException e) { - log.error("SHERPA/RoMEO query failed: ", e); - return 0; - } finally { - if (get != null) { - get.releaseConnection(); - } + // Search SHERPA for publishers with the query term in the title (name) + // a limit of 0 means the limit parameter won't be added to the API query + SHERPAPublisherResponse sherpaResponse = sherpaService.performPublisherRequest( + "publication", "title", "contains word", query, 0, 0); + + // Return the number of publishers in the response object + if (CollectionUtils.isNotEmpty(sherpaResponse.getPublishers())) { + return sherpaResponse.getPublishers().size(); } + // If other checks have failed return 0 return 0; } @@ -353,4 +169,12 @@ public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { this.sourceIdentifier = sourceIdentifier; } + /** + * Generic setter for the SHERPA Service + * @param sherpaService THe SHERPA service to be set on this SHERPAv2PublisherDataProvider + */ + public void setSherpaService(SHERPAService sherpaService) { + this.sherpaService = sherpaService; + } + } diff --git a/dspace-api/src/test/data/dspaceFolder/config/spring/api/external-services.xml b/dspace-api/src/test/data/dspaceFolder/config/spring/api/external-services.xml index 06f490eecc..c99c0c1f50 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/spring/api/external-services.xml +++ b/dspace-api/src/test/data/dspaceFolder/config/spring/api/external-services.xml @@ -8,7 +8,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dspace-api/src/test/data/dspaceFolder/config/spring/api/sherpa.xml b/dspace-api/src/test/data/dspaceFolder/config/spring/api/sherpa.xml new file mode 100644 index 0000000000..fb9e31b9a0 --- /dev/null +++ b/dspace-api/src/test/data/dspaceFolder/config/spring/api/sherpa.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + dc.identifier.issn + + + + + + + + + diff --git a/dspace-api/src/test/data/dspaceFolder/config/spring/api/spring-dspace-addon-sherpa-services.xml b/dspace-api/src/test/data/dspaceFolder/config/spring/api/spring-dspace-addon-sherpa-services.xml new file mode 100644 index 0000000000..a06a26f989 --- /dev/null +++ b/dspace-api/src/test/data/dspaceFolder/config/spring/api/spring-dspace-addon-sherpa-services.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + diff --git a/dspace-api/src/test/java/org/dspace/app/sherpa/MockSHERPAService.java b/dspace-api/src/test/java/org/dspace/app/sherpa/MockSHERPAService.java new file mode 100644 index 0000000000..d7c4877fa5 --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/app/sherpa/MockSHERPAService.java @@ -0,0 +1,135 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.sherpa; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; + +import org.dspace.app.sherpa.v2.SHERPAPublisherResponse; +import org.dspace.app.sherpa.v2.SHERPAResponse; + +/** + * Mock implementation for SHERPA API service (used by SHERPA submit service to check + * journal policies) + * This class will return mock SHERPA responses so they can be parsed and turned into external data objects downstream + * + * @author Kim Shepherd + */ +public class MockSHERPAService extends SHERPAService { + + /** + * Simple overridden 'searchByJournalISSN' so that we do attempt to build the URI but rather than make + * an actual HTTP call, return parsed SHERPAResponse for The Lancet based on known-good JSON stored with our + * test resources. + * If URI creation, parsing, or IO fails along the way, a SHERPAResponse with an error message set will be + * returned. + * @param query ISSN string to pass in an "issn equals" API query + * @return SHERPAResponse + */ + @Override + public SHERPAResponse searchByJournalISSN(String query) { + return performRequest("publication", "issn", "equals", query, 0, 1); + } + + /** + * Simple overridden performRequest so that we do attempt to build the URI but rather than make + * an actual HTTP call, return parsed SHERPAResponse for The Lancet based on known-good JSON stored with our + * test resources. + * If URI creation, parsing, or IO fails along the way, a SHERPAResponse with an error message set will be + * returned. + * @param value a journal / publication name, or ID, etc. + * @return SHERPAResponse + */ + @Override + public SHERPAResponse performRequest(String type, String field, String predicate, String value, + int start, int limit) { + try { + String endpoint = configurationService.getProperty("sherpa.romeo.url", + "https://v2.sherpa.ac.uk/cgi/retrieve"); + String apiKey = configurationService.getProperty("sherpa.romeo.apikey"); + + // Rather than search, we will simply attempt to build the URI using the real pepare method + // so that any errors there are caught, and will return a valid response for The Lancet + InputStream content = null; + try { + // Prepare the URI - this will not be used but should be evaluated + // in case a syntax exception is thrown + URI uri = prepareQuery(value, endpoint, apiKey); + if (uri == null) { + return new SHERPAResponse("Error building URI"); + } + + // Get mock JSON - in this case, a known good result for The Lancet + content = getClass().getResourceAsStream("thelancet.json"); + + // Parse JSON input stream and return response for later evaluation + return new SHERPAResponse(content, SHERPAResponse.SHERPAFormat.JSON); + + } catch (URISyntaxException e) { + // This object will be marked as having an error for later evaluation + return new SHERPAResponse(e.getMessage()); + } finally { + // Close input stream + if (content != null) { + content.close(); + } + } + } catch (IOException e) { + // This object will be marked as having an error for later evaluation + return new SHERPAResponse(e.getMessage()); + } + } + + /** + * Simple overridden performPublisherRequest so that we do attempt to build the URI but rather than make + * an actual HTTP call, return parsed SHERPAPublisherResponse for PLOS based on known-good JSON stored with our + * test resources. + * If URI creation, parsing, or IO fails along the way, a SHERPAPublisherResponse with an error message set will be + * returned. + * @param value a journal / publication name, or ID, etc. + * @return SHERPAResponse + */ + @Override + public SHERPAPublisherResponse performPublisherRequest(String type, String field, String predicate, String value, + int start, int limit) { + try { + String endpoint = configurationService.getProperty("sherpa.romeo.url", + "https://v2.sherpa.ac.uk/cgi/retrieve"); + String apiKey = configurationService.getProperty("sherpa.romeo.apikey"); + + // Rather than search, we will simply attempt to build the URI using the real pepare method + // so that any errors there are caught, and will return a valid response for The Lancet + InputStream content = null; + try { + // Prepare the URI - this will not be used but should be evaluated + // in case a syntax exception is thrown + URI uri = prepareQuery(value, endpoint, apiKey); + + // Get mock JSON - in this case, a known good result for PLOS + content = getClass().getResourceAsStream("plos.json"); + + // Parse JSON input stream and return response for later evaluation + return new SHERPAPublisherResponse(content, SHERPAPublisherResponse.SHERPAFormat.JSON); + + } catch (URISyntaxException e) { + // This object will be marked as having an error for later evaluation + return new SHERPAPublisherResponse(e.getMessage()); + } finally { + // Close input stream + if (content != null) { + content.close(); + } + } + } catch (IOException e) { + // This object will be marked as having an error for later evaluation + return new SHERPAPublisherResponse(e.getMessage()); + } + } +} diff --git a/dspace-api/src/test/java/org/dspace/app/sherpa/SHERPADataProviderTest.java b/dspace-api/src/test/java/org/dspace/app/sherpa/SHERPADataProviderTest.java new file mode 100644 index 0000000000..6b9666c830 --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/app/sherpa/SHERPADataProviderTest.java @@ -0,0 +1,355 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.sherpa; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import java.util.Optional; + +import org.apache.velocity.exception.ResourceNotFoundException; +import org.dspace.AbstractDSpaceTest; +import org.dspace.content.dto.MetadataValueDTO; +import org.dspace.external.factory.ExternalServiceFactory; +import org.dspace.external.model.ExternalDataObject; +import org.dspace.external.provider.ExternalDataProvider; +import org.dspace.external.service.ExternalDataService; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * + */ +public class SHERPADataProviderTest extends AbstractDSpaceTest { + + ExternalDataService externalDataService; + ExternalDataProvider sherpaJournalProvider; + ExternalDataProvider sherpaPublisherProvider; + ExternalDataProvider sherpaJournalIssnProvider; + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + // Set up External Service Factory and set data providers + externalDataService = ExternalServiceFactory.getInstance().getExternalDataService(); + sherpaJournalProvider = externalDataService.getExternalDataProvider("sherpaJournal"); + sherpaPublisherProvider = externalDataService.getExternalDataProvider("sherpaPublisher"); + sherpaJournalIssnProvider = + externalDataService.getExternalDataProvider("sherpaJournalIssn"); + } + + @After + public void tearDown() { + } + + /** + * Test searching the SHERPAv2JournalISSNProvider for an ISSN and inspect the returned data object + * The provider is configured to use the Mock SHERPAService. + */ + @Test + public void testGetJournalISSNExternalObject() { + // Get a response with a single valid journal, using the mock service which will return a response based on + // thelancet.json stored response in test resources + // We expect to see the following values set correctly: + // dc.title = The Lancet + // dc.identifier.issn 0140-6736 + // getId() 0140-6736 + + String validIssn = "0140-6736"; + String validName = "The Lancet"; + Optional externalDataObject = sherpaJournalIssnProvider.getExternalDataObject(validIssn); + // If data object isn't here, throw a resource not found exception + ExternalDataObject dataObject = externalDataObject.orElseThrow( + () -> new ResourceNotFoundException("Couldn't find a data object for ISSN " + validIssn)); + + // Instantiate some Strings that we'll set if we find the expected metadata + String title = null; + String identifier = null; + for (MetadataValueDTO metadataValue : dataObject.getMetadata()) { + if (metadataValue.getSchema().equalsIgnoreCase("dc") && + metadataValue.getElement().equalsIgnoreCase("title")) { + title = metadataValue.getValue(); + } else if (metadataValue.getSchema().equalsIgnoreCase("dc") + && metadataValue.getElement().equalsIgnoreCase("identifier") + && metadataValue.getQualifier().equalsIgnoreCase("issn")) { + identifier = metadataValue.getValue(); + } + } + + // Does dc.title match the expected value? + assertEquals("Title metadata must equal '" + validName + "' ", validName, title); + + // Does dc.identifier.uri match the expected value? + assertEquals("Identifier ISSN must equal " + validIssn, validIssn, identifier); + } + + /** + * Test searching the SHERPAv2JournalISSNProvider for an ISSN and inspect the returned data object + * The provider is configured to use the Mock SHERPAService. + */ + @Test + public void testSearchJournalISSNExternalObjects() { + // Get a response with a single valid journal, using the mock service which will return a response based on + // thelancet.json stored response in test resources + // We expect to see the following values set correctly: + // dc.title = The Lancet + // dc.identifier.issn 0140-6736 + // getId() 0140-6736 + + String validIssn = "0140-6736"; + String validName = "The Lancet"; + List externalDataObjects = + sherpaJournalIssnProvider.searchExternalDataObjects(validIssn, 0, 1); + + // Assert that the response is valid and not empty + assertTrue("Couldn't find a data object for publication name " + validName, + externalDataObjects != null && !externalDataObjects.isEmpty()); + + // Get the first search result for inspection + ExternalDataObject dataObject = externalDataObjects.get(0); + + // Assert that the data object itself is not null + assertNotNull("External data object must not be null", dataObject); + + // Instantiate some Strings that we'll set if we find the expected metadata + String title = null; + String identifier = null; + for (MetadataValueDTO metadataValue : dataObject.getMetadata()) { + if (metadataValue.getSchema().equalsIgnoreCase("dc") && + metadataValue.getElement().equalsIgnoreCase("title")) { + title = metadataValue.getValue(); + } else if (metadataValue.getSchema().equalsIgnoreCase("dc") + && metadataValue.getElement().equalsIgnoreCase("identifier") + && metadataValue.getQualifier().equalsIgnoreCase("issn")) { + identifier = metadataValue.getValue(); + } + } + + // Does dc.title match the expected value? + assertEquals("Title metadata must equal '" + validName + "' ", validName, title); + + // Does dc.identifier.uri match the expected value? + assertEquals("Identifier ISSN must equal " + validIssn, validIssn, identifier); + } + + /** + * Test searching the SHERPAv2JournalProvider for a journal and inspect the returned data object + * The provider is configured to use the Mock SHERPAService. + */ + @Test + public void testGetJournalExternalObject() { + // Get a response with a single valid journal, using the mock service which will return a response based on + // thelancet.json stored response in test resources + // We expect to see the following values set correctly: + // dc.title = The Lancet + // dc.identifier.issn 0140-6736 + // getId() 0140-6736 + + String validIssn = "0140-6736"; + String validName = "The Lancet"; + Optional externalDataObject = sherpaJournalProvider.getExternalDataObject(validName); + // If data object isn't here, throw a resource not found exception + ExternalDataObject dataObject = externalDataObject.orElseThrow( + () -> new ResourceNotFoundException("Couldn't find a data object for publication name " + validName)); + + // Instantiate some Strings that we'll set if we find the expected metadata + String title = null; + String identifier = null; + for (MetadataValueDTO metadataValue : dataObject.getMetadata()) { + if (metadataValue.getSchema().equalsIgnoreCase("dc") && + metadataValue.getElement().equalsIgnoreCase("title")) { + title = metadataValue.getValue(); + } else if (metadataValue.getSchema().equalsIgnoreCase("dc") + && metadataValue.getElement().equalsIgnoreCase("identifier") + && metadataValue.getQualifier().equalsIgnoreCase("issn")) { + identifier = metadataValue.getValue(); + } + } + + // Does dc.title match the expected value? + assertEquals("Title metadata must equal '" + validName + "' ", validName, title); + + // Does dc.identifier.uri match the expected value? + assertEquals("Identifier ISSN must equal " + validIssn, validIssn, identifier); + } + + /** + * Test searching the SHERPAv2JournalProvider for a journal and inspect the returned data object + * The provider is configured to use the Mock SHERPAService. + */ + @Test + public void testSearchJournalObjects() { + // Get a response with a single valid journal, using the mock service which will return a response based on + // thelancet.json stored response in test resources. We are searching here, using the search method but + // will just return 1 result since that is what our test resource matches, and is sufficient for testing + // We expect to see the following values set correctly: + // dc.title = The Lancet + // dc.identifier.issn 0140-6736 + // getId() 0140-6736 + + String validIssn = "0140-6736"; + String validName = "The Lancet"; + List externalDataObjects = + sherpaJournalProvider.searchExternalDataObjects(validName, 0, 1); + + // Assert that the response is valid and not empty + assertTrue("Couldn't find a data object for publication name " + validName, + externalDataObjects != null && !externalDataObjects.isEmpty()); + + // Get the first search result for inspection + ExternalDataObject dataObject = externalDataObjects.get(0); + + // Assert that the data object itself is not null + assertNotNull("External data object must not be null", dataObject); + + // Instantiate some Strings that we'll set if we find the expected metadata + String title = null; + String identifier = null; + for (MetadataValueDTO metadataValue : dataObject.getMetadata()) { + if (metadataValue.getSchema().equalsIgnoreCase("dc") && + metadataValue.getElement().equalsIgnoreCase("title")) { + title = metadataValue.getValue(); + } else if (metadataValue.getSchema().equalsIgnoreCase("dc") + && metadataValue.getElement().equalsIgnoreCase("identifier") + && metadataValue.getQualifier().equalsIgnoreCase("issn")) { + identifier = metadataValue.getValue(); + } + } + + // Does dc.title match the expected value? + assertEquals("Title metadata must equal '" + validName + "' ", validName, title); + + // Does dc.identifier.uri match the expected value? + assertEquals("Identifier ISSN must equal " + validIssn, validIssn, identifier); + } + + /** + * Test searching the SHERPAv2JournalProvider for a journal and inspect the returned data object + * The provider is configured to use the Mock SHERPAService. + */ + @Test + public void testGetPublisherExternalObject() { + // Get a response with a single valid ISSN, using the mock service which will return a response based on + // thelancet.json stored response in test resources + // We expect to see the following values set correctly: + // dc.title = Public Library of Science + // dc.identifier.sherpaPublisher 112 + // dc.identifier.other http://www.plos.org/ + + // Set expected values + String validName = "Public Library of Science"; + String validIdentifier = "112"; + String validUrl = "http://www.plos.org/"; + + // Retrieve the dataobject(s) from the data provider + Optional externalDataObject = sherpaPublisherProvider.getExternalDataObject(validName); + // If data object isn't here, throw a resource not found exception + ExternalDataObject dataObject = externalDataObject.orElseThrow( + () -> new ResourceNotFoundException("Couldn't find a data object for publication name " + validName)); + + // Instantiate some Strings that we'll set if we find the expected metadata + String title = null; + String identifier = null; + String url = null; + for (MetadataValueDTO metadataValue : dataObject.getMetadata()) { + if (metadataValue.getSchema().equalsIgnoreCase("dc") && + metadataValue.getElement().equalsIgnoreCase("title")) { + title = metadataValue.getValue(); + } else if (metadataValue.getSchema().equalsIgnoreCase("dc") + && metadataValue.getElement().equalsIgnoreCase("identifier") + && metadataValue.getQualifier().equalsIgnoreCase("sherpaPublisher")) { + identifier = metadataValue.getValue(); + } else if (metadataValue.getSchema().equalsIgnoreCase("dc") + && metadataValue.getElement().equalsIgnoreCase("identifier") + && metadataValue.getQualifier().equalsIgnoreCase("other")) { + url = metadataValue.getValue(); + } + } + + // Does dc.title match the expected value? + assertEquals("Title metadata must equal '" + validName + "' ", validName, title); + + // Does dc.identifier.sherpaPublisher match the expected value? + assertEquals("Publisher ID must equal " + validIdentifier, validIdentifier, identifier); + + // Does dc.identifier.other match the expected value? + assertEquals("Publisher URL must equal " + validUrl, validUrl, url); + } + + /** + * Test searching the SHERPAv2JournalProvider for a journal and inspect the returned data object + * The provider is configured to use the Mock SHERPAService. + */ + @Test + public void testSearchPublisherExternalObjects() { + // Get a response with a single valid ISSN, using the mock service which will return a response based on + // thelancet.json stored response in test resources + // We expect to see the following values set correctly: + // dc.title = Public Library of Science + // dc.identifier.sherpaPublisher 112 + // dc.identifier.other http://www.plos.org/ + + // Set expected values + String validName = "Public Library of Science"; + String validIdentifier = "112"; + String validUrl = "http://www.plos.org/"; + + // Retrieve the dataobject(s) from the data provider + List externalDataObjects = + sherpaPublisherProvider.searchExternalDataObjects(validName, 0, 1); + + // Assert that the response is valid and not empty + assertTrue("Couldn't find a data object for publication name " + validName, + externalDataObjects != null && !externalDataObjects.isEmpty()); + + ExternalDataObject dataObject = externalDataObjects.get(0); + + // Assert that the data object itself is not null + assertNotNull("External data object must not be null", dataObject); + + // Instantiate some Strings that we'll set if we find the expected metadata + String title = null; + String identifier = null; + String url = null; + for (MetadataValueDTO metadataValue : dataObject.getMetadata()) { + if (metadataValue.getSchema().equalsIgnoreCase("dc") && + metadataValue.getElement().equalsIgnoreCase("title")) { + title = metadataValue.getValue(); + } else if (metadataValue.getSchema().equalsIgnoreCase("dc") + && metadataValue.getElement().equalsIgnoreCase("identifier") + && metadataValue.getQualifier().equalsIgnoreCase("sherpaPublisher")) { + identifier = metadataValue.getValue(); + } else if (metadataValue.getSchema().equalsIgnoreCase("dc") + && metadataValue.getElement().equalsIgnoreCase("identifier") + && metadataValue.getQualifier().equalsIgnoreCase("other")) { + url = metadataValue.getValue(); + } + } + + // Does dc.title match the expected value? + assertEquals("Title metadata must equal '" + validName + "' ", validName, title); + + // Does dc.identifier.sherpaPublisher match the expected value? + assertEquals("Publisher ID must equal " + validIdentifier, validIdentifier, identifier); + + // Does dc.identifier.other match the expected value? + assertEquals("Publisher URL must equal " + validUrl, validUrl, url); + } +} \ No newline at end of file diff --git a/dspace-api/src/test/java/org/dspace/app/sherpa/SHERPAServiceTest.java b/dspace-api/src/test/java/org/dspace/app/sherpa/SHERPAServiceTest.java new file mode 100644 index 0000000000..e6c3f4d073 --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/app/sherpa/SHERPAServiceTest.java @@ -0,0 +1,237 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.sherpa; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.UnsupportedEncodingException; +import java.net.URISyntaxException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.utils.URIBuilder; +import org.dspace.AbstractDSpaceTest; +import org.dspace.app.sherpa.v2.SHERPAPublisherResponse; +import org.dspace.app.sherpa.v2.SHERPAResponse; +import org.dspace.app.sherpa.v2.SHERPAUtils; +import org.dspace.services.ConfigurationService; +import org.dspace.services.factory.DSpaceServicesFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Integration tests for SHERPA service + * @author Kim Shepherd + * @see MockSHERPAService + */ +public class SHERPAServiceTest extends AbstractDSpaceTest { + + protected ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); + + // Spring SHERPA service. For testing purposes, this will use a mock service + // that doesn't perform actual HTTP queries but does construct URIs + // and returns a valid response (The Lancet) if no other errors are encountered + protected SHERPAService sherpaService = DSpaceServicesFactory.getInstance().getServiceManager() + .getServiceByName("org.dspace.app.sherpa.MockSHERPAService", MockSHERPAService.class); + + public SHERPAServiceTest() { + + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + /** + * Test searching by Journal ISSN directly against SHERPA service + */ + @Test + public void testSearchByJournalISSN() { + // Get a response with a single valid ISSN, using the mock service which will return a response based on + // thelancet.json stored response in test resources + String validISSN = "0140-6736"; + SHERPAResponse sherpaResponse = sherpaService.searchByJournalISSN(validISSN); + + // This response should NOT contain an error (isError() should be false) + assertFalse("Response contained an error flag / message: " + sherpaResponse.getMessage(), + sherpaResponse.isError()); + + // This response should contain a single journal called The Lancet + String expectedTitle = "The Lancet"; + assertTrue("Response did not contain a journal with the expected title '" + expectedTitle + '"', + expectedTitle.equals(sherpaResponse.getJournals().get(0).getTitles().get(0))); + } + + /** + * Test that the URIBuilder and sanitation procedures are producing expected URLs, comparing the results + * to manually compiled strings + * @throws URISyntaxException + */ + @Test + public void testUriConstruction() throws URISyntaxException, UnsupportedEncodingException { + // Get values for base URL and api key parameter + String endpoint = configurationService.getProperty("sherpa.romeo.url", + "https://v2.sherpa.ac.uk/cgi/retrieve"); + String apiKey = configurationService.getProperty("sherpa.romeo.apikey", null); + + // Compare expected outputs + // Valid ISSN (The Lancet) + String validISSN = "0140-6736"; + // Invalid ISSN that also contains characters we strip out in sanitisation + String invalidISSN = "{TEST}"; + + // Characters like { and } that conflict with JSON should be stripped from the filter query + assertEquals("JSON filter query sanitisation not stripping special characters", + "TEST", SHERPAUtils.sanitiseQuery(invalidISSN)); + + // The valid string should look like this (assuming default configuration) + // https://v2.sherpa.ac.uk/cgi/retrieve?item-type=publication&filter=[["issn","equals","0140-6736"]]&format=Json + String validUrl = new URIBuilder(buildUrlString(validISSN, endpoint, apiKey)).toString(); + assertEquals("Built and expected valid URLs differ", validUrl, + sherpaService.constructHttpGet("publication", "issn", "equals", validISSN) + .getURI().toASCIIString()); + + // The invalid string should look like this (assuming default configuration) + // https://v2.sherpa.ac.uk/cgi/retrieve?item-type=publication&filter=[["issn","equals","TEST"]]&format=Json + // Note - it should return 0 results from the API, but these services are not intended to validate the ISSN + // query, though they do sanitise it for the JSON input type, hence expecting the braces to be stripped + String invalidUrl = new URIBuilder(buildUrlString(invalidISSN, endpoint, apiKey)).toString(); + assertEquals("Built and expected invalid URLs differ", invalidUrl, + sherpaService.constructHttpGet("publication", "issn", "equals", invalidISSN) + .getURI().toASCIIString()); + + + // The null query string should look like this (assuming default configuration) + // https://v2.sherpa.ac.uk/cgi/retrieve?item-type=publication&filter=[["issn","equals",""]]&format=Json + // Note - it should return 0 results from the API, but all we do is log a warning, this is not considered + // a fatal URI syntax exception (the remote call does work, and returns 0 items as valid JSON) + String nullUrl = new URIBuilder(buildUrlString(null, endpoint, apiKey)).toString(); + assertEquals("Built and expected invalid URLs differ", nullUrl, + sherpaService.constructHttpGet("publication", "issn", "equals", null) + .getURI().toASCIIString()); + + } + + /** + * Thorough test of returned SHERPAResponse object to ensure all expected fields are there and valid + */ + @Test + public void testJournalResponse() { + // Valid ISSN (The Lancet) + String validISSN = "0140-6736"; + SHERPAResponse response = sherpaService.searchByJournalISSN(validISSN); + + // Assert response is not error, or fail with message + assertFalse("Response was flagged as 'isError'", response.isError()); + + // Assert response has at least one journal result, or fail with message + assertTrue("List of journals did not contain at least one parsed journal", + CollectionUtils.isNotEmpty(response.getJournals())); + + // Assert response has a journal with title "The Lancet", or fail with message + String expectedTitle = "The Lancet"; + assertTrue("Journal title did not match expected '" + expectedTitle + "' value", + CollectionUtils.isNotEmpty(response.getJournals().get(0).getTitles()) + && expectedTitle.equals(response.getJournals().get(0).getTitles().get(0))); + + // Assert response has expected publication (metadata) URI + String expectedSystemMetadataUri = "http://v2.sherpa.ac.uk/id/publication/23803"; + assertTrue("Response metadata URI did not match expected '" + expectedSystemMetadataUri + + "' value", expectedSystemMetadataUri.equals(response.getMetadata().getUri())); + + // Assert response has at least one policy + assertTrue("Response did not contain at least one archiving policy", + CollectionUtils.isNotEmpty(response.getJournals().get(0).getPolicies())); + + // Assert response has at least one permitted version + assertTrue("Response did not contain at least one permitted version", + CollectionUtils.isNotEmpty(response.getJournals().get(0).getPolicies().get(0).getPermittedVersions())); + + // Assert journal has at least one publisher + assertTrue("Response did not contain at least one publisher", + CollectionUtils.isNotEmpty(response.getJournals().get(0).getPublishers())); + + // Assert first publisher has name 'Elsevier' + String expectedPublisherName = "Elsevier"; + assertTrue("Response did not contain expected publisher name '" + expectedPublisherName + "'", + expectedPublisherName.equals(response.getJournals().get(0).getPublisher().getName())); + } + + /** + * Thorough test of returned SHERPAPublisherResponse object to ensure all expected fields are there and valid + */ + @Test + public void testPublisherResponse() { + // Set up basic query and query the (mock) service + String publisherName = "Public Library of Science"; + SHERPAPublisherResponse response = sherpaService.performPublisherRequest( + "publisher", "name", "equals", publisherName, 0, 1); + + // Assert response is not error, or fail with message + assertFalse("Response was flagged as 'isError'", response.isError()); + + // Assert response has at least one publisher result, or fail with message + assertTrue("List of publishers did not contain at least one parsed publisher", + CollectionUtils.isNotEmpty(response.getPublishers())); + + // Assert response has a publisher with name "Public Library of Science", or fail with message + String expectedName = "Public Library of Science"; + assertEquals("Publisher name did not match expected '" + expectedName + "' value", + expectedName, response.getPublishers().get(0).getName()); + + // Assert response has expected publisher URL + String expectedUrl = "http://www.plos.org/"; + assertEquals("Response metadata URI did not match expected '" + expectedUrl + + "' value", expectedUrl, response.getPublishers().get(0).getUri()); + + // Assert response has at expected publisher ID + String expectedId = "112"; + assertEquals("Response publisher ID did not match expected ID " + expectedId, + expectedId, response.getPublishers().get(0).getIdentifier()); + } + + /** + * Build URL manually with string builder to compare to URIBuilder usage in actual service + * @param query + * @param endpoint + * @param apiKey + * @return + */ + public static String buildUrlString(String query, String endpoint, String apiKey) { + query = SHERPAUtils.sanitiseQuery(query); + StringBuilder expected = new StringBuilder(); + String filter = "[[\"issn\",\"equals\",\"" + query + "\"]]"; + expected.append(endpoint).append("?") + .append("item-type=publication&filter=").append(URLEncoder.encode(filter, StandardCharsets.UTF_8)) + .append("&format=Json&offset=0&limit=1"); + if (StringUtils.isNotBlank(apiKey)) { + expected.append("&api-key=").append(apiKey); + } + return expected.toString(); + } + +} diff --git a/dspace-api/src/test/java/org/dspace/app/sherpa/submit/SHERPASubmitServiceTest.java b/dspace-api/src/test/java/org/dspace/app/sherpa/submit/SHERPASubmitServiceTest.java new file mode 100644 index 0000000000..1eaa916f56 --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/app/sherpa/submit/SHERPASubmitServiceTest.java @@ -0,0 +1,128 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.sherpa.submit; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.sql.SQLException; +import java.util.List; + +import org.dspace.AbstractUnitTest; +import org.dspace.app.sherpa.v2.SHERPAResponse; +import org.dspace.authorize.AuthorizeException; +import org.dspace.content.Collection; +import org.dspace.content.Community; +import org.dspace.content.Item; +import org.dspace.content.MetadataField; +import org.dspace.content.MetadataSchemaEnum; +import org.dspace.content.MetadataValue; +import org.dspace.content.WorkspaceItem; +import org.dspace.content.factory.ContentServiceFactory; +import org.dspace.content.service.CollectionService; +import org.dspace.content.service.CommunityService; +import org.dspace.content.service.InstallItemService; +import org.dspace.content.service.ItemService; +import org.dspace.content.service.MetadataFieldService; +import org.dspace.content.service.MetadataValueService; +import org.dspace.content.service.WorkspaceItemService; +import org.dspace.services.factory.DSpaceServicesFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * SHERPASubmitServiceTest creates a dummy item with an ISSN in its metadata, and makes sure + * that the ISSN is detected and passed to SHERPAService for a mock query + */ +public class SHERPASubmitServiceTest extends AbstractUnitTest { + + // Set up services + protected ItemService itemService = ContentServiceFactory.getInstance().getItemService(); + protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); + protected InstallItemService installItemService = ContentServiceFactory.getInstance().getInstallItemService(); + protected CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService(); + protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService(); + protected MetadataFieldService metadataFieldService = ContentServiceFactory.getInstance().getMetadataFieldService(); + protected MetadataValueService metadataValueService = ContentServiceFactory.getInstance().getMetadataValueService(); + SHERPASubmitService sherpaSubmitService = DSpaceServicesFactory.getInstance().getServiceManager() + .getServiceByName("org.dspace.app.sherpa.submit.SHERPASubmitService", SHERPASubmitService.class); + Collection testCollection = null; + Community testCommunity = null; + + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + + } + + @Before + public void setUp() throws SQLException, AuthorizeException { + context.turnOffAuthorisationSystem(); + // Create primary Test community + testCommunity = communityService.create(null, context); + communityService + .addMetadata(context, testCommunity, MetadataSchemaEnum.DC.getName(), + "title", null, null, "Test Community"); + communityService.update(context, testCommunity); + + // Create our primary Test Collection + testCollection = collectionService.create(context, testCommunity); + collectionService.addMetadata(context, testCollection, "dc", "title", null, null, + "Test Collection"); + collectionService.update(context, testCollection); + } + + @After + public void tearDown() { + context.restoreAuthSystemState(); + testCommunity = null; + testCollection = null; + } + + /** + * Test the ISSN extraction + */ + @Test + public void testGetISSNs() throws AuthorizeException, SQLException { + String validISSN = "0140-6736"; + // Create and install an item with an ISSN + WorkspaceItem testWorkspaceItem = workspaceItemService.create(context, testCollection, false); + Item testItem = installItemService.installItem(context, testWorkspaceItem); + + // Set up ISSN metadatavalue + MetadataField issnField = metadataFieldService. + findByString(context, "dc.identifier.issn", '.'); + MetadataValue metadataValue = metadataValueService.create(context, testItem, issnField); + metadataValue.setValue(validISSN); + + // Get responses from SHERPA submit service, which should inspect item ISSNs and perform search + // on the mock SHERPA service + List responses = sherpaSubmitService.searchRelatedJournals(context, testItem); + + // Make sure response is not null or empty + assertTrue("Response list should not be null or empty", + responses != null && !responses.isEmpty()); + + // For each response (there should be only one based on test data) perform the standard set + // of thorough parsing tests + for (SHERPAResponse response : responses) { + // Assert response is not error, or fail with message + assertFalse("Response was flagged as 'isError'", response.isError()); + + // Skip remainder of parsing tests - these are already done in SHERPAServiceTEst + } + } + +} diff --git a/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java b/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java deleted file mode 100644 index 25676b93fd..0000000000 --- a/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAPublisherResponseTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.app.sherpa.v2; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.commons.collections4.CollectionUtils; -import org.dspace.AbstractDSpaceTest; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * @author Kim Shepherd - */ -public class SHERPAPublisherResponseTest extends AbstractDSpaceTest { - - public SHERPAPublisherResponseTest() { - - } - - @BeforeClass - public static void setUpClass() { - } - - @AfterClass - public static void tearDownClass() { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } - - /** - * Test that the SHERPA API response (in this case saved as local JSON) is correctly - * parsed and resulting objects have expected values - * @throws IOException - */ - @Test - public void testParseJSON() throws IOException { - - InputStream content = null; - try { - // Get mock JSON - in this case, a known good result for PLOS - content = getClass().getResourceAsStream("plos.json"); - - // Parse JSON input stream - SHERPAPublisherResponse response = new SHERPAPublisherResponse(content, - SHERPAPublisherResponse.SHERPAFormat.JSON); - - // Assert response is not error, or fail with message - assertFalse("Response was flagged as 'isError'", response.isError()); - - // Assert response has at least one publisher result, or fail with message - assertTrue("List of publishers did not contain at least one parsed publisher", - CollectionUtils.isNotEmpty(response.getPublishers())); - - // Assert response has a publisher with name "Public Library of Science", or fail with message - String expectedName = "Public Library of Science"; - assertEquals("Publisher name did not match expected '" + expectedName + "' value", - expectedName, response.getPublishers().get(0).getName()); - - // Assert response has expected publisher URL - String expectedUrl = "http://www.plos.org/"; - assertEquals("Response metadata URI did not match expected '" + expectedUrl - + "' value", expectedUrl, response.getPublishers().get(0).getUri()); - - // Assert response has at expected publisher ID - String expectedId = "112"; - assertEquals("Response publisher ID did not match expected ID " + expectedId, - expectedId, response.getPublishers().get(0).getIdentifier()); - - } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); - } finally { - if (content != null) { - content.close(); - } - } - } -} diff --git a/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java b/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java deleted file mode 100644 index d171a8b77a..0000000000 --- a/dspace-api/src/test/java/org/dspace/app/sherpa/v2/SHERPAResponseTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.app.sherpa.v2; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.io.InputStream; - -import org.apache.commons.collections4.CollectionUtils; -import org.dspace.AbstractDSpaceTest; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * @author Kim Shepherd - */ -public class SHERPAResponseTest extends AbstractDSpaceTest { - - public SHERPAResponseTest() { - - } - - @BeforeClass - public static void setUpClass() { - } - - @AfterClass - public static void tearDownClass() { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } - - /** - * Test that the SHERPA API response (in this case saved as local JSON) is correctly - * parsed and resulting objects have expected values - * @throws IOException - */ - @Test - public void testParseJSON() throws IOException { - - InputStream content = null; - try { - // Get mock JSON - in this case, a known good result for The Lancet - content = getClass().getResourceAsStream("thelancet.json"); - - // Parse JSON input stream - SHERPAResponse response = new SHERPAResponse(content, SHERPAResponse.SHERPAFormat.JSON); - - // Assert response is not error, or fail with message - assertFalse("Response was flagged as 'isError'", response.isError()); - - // Assert response has at least one journal result, or fail with message - assertTrue("List of journals did not contain at least one parsed journal", - CollectionUtils.isNotEmpty(response.getJournals())); - - // Assert response has a journal with title "The Lancet", or fail with message - String expectedTitle = "The Lancet"; - assertTrue("Journal title did not match expected '" + expectedTitle + "' value", - CollectionUtils.isNotEmpty(response.getJournals().get(0).getTitles()) - && expectedTitle.equals(response.getJournals().get(0).getTitles().get(0))); - - // Assert response has expected publication (metadata) URI - String expectedSystemMetadataUri = "http://v2.sherpa.ac.uk/id/publication/23803"; - assertTrue("Response metadata URI did not match expected '" + expectedSystemMetadataUri - + "' value", expectedSystemMetadataUri.equals(response.getMetadata().getUri())); - - // Assert response has at least one policy - assertTrue("Response did not contain at least one archiving policy", - CollectionUtils.isNotEmpty(response.getJournals().get(0).getPolicies())); - - // Assert response has at least one permitted version - assertTrue("Response did not contain at least one permitted version", - CollectionUtils.isNotEmpty(response.getJournals().get(0).getPolicies().get(0).getPermittedVersions())); - - // Assert journal has at least one publisher - assertTrue("Response did not contain at least one publisher", - CollectionUtils.isNotEmpty(response.getJournals().get(0).getPublishers())); - - // Assert first publisher has name 'Elsevier' - String expectedPublisherName = "Elsevier"; - assertTrue("Response did not contain expected publisher name '" + expectedPublisherName + "'", - expectedPublisherName.equals(response.getJournals().get(0).getPublisher().getName())); - } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); - } finally { - if (content != null) { - content.close(); - } - } - } -} diff --git a/dspace-api/src/test/resources/org/dspace/app/sherpa/v2/plos.json b/dspace-api/src/test/resources/org/dspace/app/sherpa/plos.json similarity index 100% rename from dspace-api/src/test/resources/org/dspace/app/sherpa/v2/plos.json rename to dspace-api/src/test/resources/org/dspace/app/sherpa/plos.json diff --git a/dspace-api/src/test/resources/org/dspace/app/sherpa/v2/thelancet.json b/dspace-api/src/test/resources/org/dspace/app/sherpa/thelancet.json similarity index 100% rename from dspace-api/src/test/resources/org/dspace/app/sherpa/v2/thelancet.json rename to dspace-api/src/test/resources/org/dspace/app/sherpa/thelancet.json diff --git a/dspace/config/spring/api/external-services.xml b/dspace/config/spring/api/external-services.xml index b9bdc7f33d..5a938568d5 100644 --- a/dspace/config/spring/api/external-services.xml +++ b/dspace/config/spring/api/external-services.xml @@ -5,11 +5,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + From 8fc804a8362095c268d0045570103528ec0bdbbd Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 22 Jan 2021 16:10:16 +1300 Subject: [PATCH 048/179] [DS-3940] Remove unused import in SHERPAv2JournalDataProvider --- .../external/provider/impl/SHERPAv2JournalDataProvider.java | 1 - 1 file changed, 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java index 10df1790bd..42d3cab494 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/SHERPAv2JournalDataProvider.java @@ -15,7 +15,6 @@ import java.util.stream.Collectors; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.http.impl.client.CloseableHttpClient; import org.apache.logging.log4j.Logger; import org.dspace.app.sherpa.SHERPAService; import org.dspace.app.sherpa.v2.SHERPAJournal; From aa16ef717934c2e524c4183f91ed4193d544ceb2 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 22 Jan 2021 16:57:09 +1300 Subject: [PATCH 049/179] [DS-3940] Update ExternalSourcesRestControllerIT to count for new external sources --- .../config/spring/api/external-services.xml | 2 +- .../app/rest/ExternalSourcesRestControllerIT.java | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/test/data/dspaceFolder/config/spring/api/external-services.xml b/dspace-api/src/test/data/dspaceFolder/config/spring/api/external-services.xml index c99c0c1f50..9eb8dd322b 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/spring/api/external-services.xml +++ b/dspace-api/src/test/data/dspaceFolder/config/spring/api/external-services.xml @@ -12,6 +12,7 @@ + @@ -19,7 +20,6 @@ - diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ExternalSourcesRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ExternalSourcesRestControllerIT.java index 25048760c2..5f98674de6 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ExternalSourcesRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ExternalSourcesRestControllerIT.java @@ -26,9 +26,15 @@ public class ExternalSourcesRestControllerIT extends AbstractControllerIntegrati .andExpect(status().isOk()) .andExpect(jsonPath("$._embedded.externalsources", Matchers.hasItems( ExternalSourceMatcher.matchExternalSource("mock", "mock", false), - ExternalSourceMatcher.matchExternalSource("orcid", "orcid", false) + ExternalSourceMatcher.matchExternalSource("orcid", "orcid", false), + ExternalSourceMatcher.matchExternalSource( + "sherpaJournalIssn", "sherpaJournalIssn", false), + ExternalSourceMatcher.matchExternalSource( + "sherpaJournal", "sherpaPublisher", false), + ExternalSourceMatcher.matchExternalSource( + "sherpaPublisher", "sherpaPublisher", false) ))) - .andExpect(jsonPath("$.page.totalElements", Matchers.is(2))); + .andExpect(jsonPath("$.page.totalElements", Matchers.is(5))); } @Test From 1d9b9c6c41116fbfd16a9ba0cab938dd54c2b5c3 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 22 Jan 2021 19:02:55 +1300 Subject: [PATCH 050/179] [DS-3940] Correct typo in ExternalSourcesRestControllerIT --- .../org/dspace/app/rest/ExternalSourcesRestControllerIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ExternalSourcesRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ExternalSourcesRestControllerIT.java index 5f98674de6..5297415172 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ExternalSourcesRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ExternalSourcesRestControllerIT.java @@ -30,7 +30,7 @@ public class ExternalSourcesRestControllerIT extends AbstractControllerIntegrati ExternalSourceMatcher.matchExternalSource( "sherpaJournalIssn", "sherpaJournalIssn", false), ExternalSourceMatcher.matchExternalSource( - "sherpaJournal", "sherpaPublisher", false), + "sherpaPublisher", "sherpaPublisher", false), ExternalSourceMatcher.matchExternalSource( "sherpaPublisher", "sherpaPublisher", false) ))) From 4a2152c48282fe6769a7d5848c90b0681925bc04 Mon Sep 17 00:00:00 2001 From: Bruno Roemers Date: Mon, 25 Jan 2021 09:45:38 +0100 Subject: [PATCH 051/179] 76179: Move DateMathParser to dspace-api module DateMathParser will be needed in AccessConditionOption, so this change is needed to avoid a circular dependency (dspace-api -> dspace-server-webapp). --- .../src/main/java/org/dspace/util}/DateMathParser.java | 2 +- .../app/rest/repository/SubmissionUploadRestRepository.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename {dspace-server-webapp/src/main/java/org/dspace/app/rest/utils => dspace-api/src/main/java/org/dspace/util}/DateMathParser.java (99%) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/DateMathParser.java b/dspace-api/src/main/java/org/dspace/util/DateMathParser.java similarity index 99% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/DateMathParser.java rename to dspace-api/src/main/java/org/dspace/util/DateMathParser.java index 8a59c23336..7c3e13a28e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/DateMathParser.java +++ b/dspace-api/src/main/java/org/dspace/util/DateMathParser.java @@ -5,7 +5,7 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.rest.utils; +package org.dspace.util; import java.text.ParseException; import java.time.Instant; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java index 4a4614183b..ffefd1daac 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java @@ -17,12 +17,12 @@ import org.apache.logging.log4j.Logger; import org.dspace.app.rest.model.AccessConditionOptionRest; import org.dspace.app.rest.model.SubmissionUploadRest; import org.dspace.app.rest.projection.Projection; -import org.dspace.app.rest.utils.DateMathParser; import org.dspace.core.Context; import org.dspace.eperson.service.GroupService; import org.dspace.submit.model.AccessConditionOption; import org.dspace.submit.model.UploadConfiguration; import org.dspace.submit.model.UploadConfigurationService; +import org.dspace.util.DateMathParser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; From 5f68a227da3ea5bae85eff35b65858dede3175a6 Mon Sep 17 00:00:00 2001 From: Bruno Roemers Date: Mon, 25 Jan 2021 20:59:05 +0100 Subject: [PATCH 052/179] 74236: Implement boundary checks --- .../submit/model/AccessConditionOption.java | 41 ++++++++++++++++++- .../impl/BitstreamResourcePolicyUtils.java | 5 ++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java b/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java index 1c13f99398..22898a8a38 100644 --- a/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java +++ b/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java @@ -8,6 +8,7 @@ package org.dspace.submit.model; import java.sql.SQLException; +import java.text.ParseException; import java.util.Date; import org.dspace.authorize.AuthorizeException; @@ -18,6 +19,7 @@ import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.eperson.Group; import org.dspace.eperson.service.GroupService; +import org.dspace.util.DateMathParser; import org.springframework.beans.factory.annotation.Autowired; /** @@ -38,6 +40,8 @@ public class AccessConditionOption { @Autowired GroupService groupService; + DateMathParser dateMathParser = new DateMathParser(); + /** An unique name identifying the access contion option **/ private String name; @@ -140,7 +144,8 @@ public class AccessConditionOption { } public void createResourcePolicy(Context context, Bitstream b, String name, String description, - Date startDate, Date endDate) throws SQLException, AuthorizeException { + Date startDate, Date endDate) + throws SQLException, AuthorizeException, ParseException { if (getHasStartDate() && startDate == null) { throw new IllegalStateException("The access condition " + getName() + " requires a start date."); } @@ -153,7 +158,39 @@ public class AccessConditionOption { if (!getHasEndDate() && endDate != null) { throw new IllegalStateException("The access condition " + getName() + " cannot contain an end date."); } - //TODO: check date limits as well + + Date earliestStartDate = null; + if (getStartDateLimit() != null) { + earliestStartDate = dateMathParser.parseMath(getStartDateLimit()); + } + + Date latestEndDate = null; + if (getEndDateLimit() != null) { + latestEndDate = dateMathParser.parseMath(getEndDateLimit()); + } + + // throw if latestEndDate before earliestStartDate + if (earliestStartDate != null && latestEndDate != null && earliestStartDate.compareTo(latestEndDate) > 0) { + throw new IllegalStateException(String.format( + "The boundaries of %s overlap: [%s, %s]", getName(), getStartDateLimit(), getEndDateLimit() + )); + } + + // throw if startDate before earliestStartDate + if (earliestStartDate != null && earliestStartDate.compareTo(startDate) > 0) { + throw new IllegalStateException(String.format( + "The start date of access condition %s should be later than %s from now.", + getName(), getStartDateLimit() + )); + } + + // throw if endDate after latestEndDate + if (latestEndDate != null && latestEndDate.compareTo(endDate) < 0) { + throw new IllegalStateException(String.format( + "The end date of access condition %s should be earlier than %s from now.", getName(), getEndDateLimit() + )); + } + Group group = groupService.findByName(context, getGroupName()); authorizeService.createResourcePolicy(context, b, group, null, Constants.READ, ResourcePolicy.TYPE_CUSTOM, name, description, startDate, diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyUtils.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyUtils.java index 4b9a0ae133..7261aa86b3 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyUtils.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/BitstreamResourcePolicyUtils.java @@ -8,6 +8,7 @@ package org.dspace.app.rest.submit.factory.impl; import java.sql.SQLException; +import java.text.ParseException; import java.util.Date; import java.util.Iterator; @@ -47,7 +48,7 @@ public class BitstreamResourcePolicyUtils { */ public static void findApplyResourcePolicy(Context context, Iterator uploadConfigs, Bitstream b, UploadBitstreamAccessConditionDTO newAccessCondition) - throws SQLException, AuthorizeException { + throws SQLException, AuthorizeException, ParseException { String name = newAccessCondition.getName(); String description = newAccessCondition.getDescription(); @@ -75,7 +76,7 @@ public class BitstreamResourcePolicyUtils { public static void findApplyResourcePolicy(Context context, Iterator uploadConfigs, Bitstream b, String name, String description, Date startDate, Date endDate) - throws SQLException, AuthorizeException { + throws SQLException, AuthorizeException, ParseException { while (uploadConfigs .hasNext()) { UploadConfiguration uploadConfiguration = uploadConfigs.next(); From 8f7a67e1a5d9c84c574e6b4a4fdb7359fd505d41 Mon Sep 17 00:00:00 2001 From: Bruno Roemers Date: Mon, 25 Jan 2021 23:24:56 +0100 Subject: [PATCH 053/179] 74236: WIP: Write tests --- .../rest/WorkspaceItemRestRepositoryIT.java | 374 ++++++++++++++++-- 1 file changed, 338 insertions(+), 36 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java index 7b0bbe6157..14bc1d0a09 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java @@ -25,7 +25,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import java.io.InputStream; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -36,6 +38,7 @@ import javax.ws.rs.core.MediaType; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.CharEncoding; +import org.apache.commons.lang3.time.DateUtils; import org.dspace.app.rest.matcher.CollectionMatcher; import org.dspace.app.rest.matcher.ItemMatcher; import org.dspace.app.rest.matcher.MetadataMatcher; @@ -3364,60 +3367,62 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration context.restoreAuthSystemState(); + // date + SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd"); + Date startDate = DateUtils.addYears(new Date(), 4); + String startDateStr = dateFmt.format(startDate); + // create a list of values to use in add operation - List addAccessCondition = new ArrayList(); - Map value = new HashMap(); - value.put("name", "embargoedWithGroupSelect"); - value.put("groupUUID", embargoedGroup1.getID().toString()); - value.put("endDate", "2020-01-01"); + List addAccessCondition = new ArrayList<>(); + Map value = new HashMap<>(); + value.put("name", "embargo"); + value.put("startDate", startDateStr); addAccessCondition.add(new AddOperation("/sections/upload/files/0/accessConditions/-", value)); String patchBody = getPatchContent(addAccessCondition); String authToken = getAuthToken(eperson.getEmail(), password); - getClient(authToken).perform(patch("/api/submission/workspaceitems/" + witem.getID()) - .content(patchBody) - .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$",Matchers.allOf( - hasJsonPath("$.sections.upload.files[0].accessConditions[0].name", - is("embargoedWithGroupSelect")), - hasJsonPath("$.sections.upload.files[0].accessConditions[0].endDate", - is("2020-01-01")), - hasJsonPath("$.sections.upload.files[0].accessConditions[0].groupUUID", - is(embargoedGroup1.getID().toString())) - ))); + getClient(authToken) + .perform( + patch("/api/submission/workspaceitems/" + witem.getID()) + .content(patchBody) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON) + ) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("embargo"))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", is(startDateStr))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", nullValue())); // verify that the patch changes have been persisted getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID())) .andExpect(status().isOk()) - .andExpect(jsonPath("$",Matchers.allOf( - hasJsonPath("$.sections.upload.files[0].accessConditions[0].name", - is("embargoedWithGroupSelect")), - hasJsonPath("$.sections.upload.files[0].accessConditions[0].endDate", - is("2020-01-01")), - hasJsonPath("$.sections.upload.files[0].accessConditions[0].groupUUID", - is(embargoedGroup1.getID().toString())) - ))); + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("embargo"))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", is(startDateStr))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", nullValue())); // create a list of values to use in remove operation - List removeAccessCondition = new ArrayList(); + List removeAccessCondition = new ArrayList<>(); removeAccessCondition.add(new RemoveOperation("/sections/upload/files/0/accessConditions")); + // remove and verify that access conditions are set to defaults String patchReplaceBody = getPatchContent(removeAccessCondition); - getClient(authToken).perform(patch("/api/submission/workspaceitems/" + witem.getID()) - .content(patchReplaceBody) - .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$",Matchers.allOf( - hasJsonPath("$.sections.upload.files[0].accessConditions",hasSize(0))))); + getClient(authToken) + .perform( + patch("/api/submission/workspaceitems/" + witem.getID()) + .content(patchReplaceBody) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON) + ) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", nullValue())) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", nullValue())); // verify that the patch changes have been persisted getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$",Matchers.allOf( - hasJsonPath("$.sections.upload.files[0].accessConditions", hasSize(0)) - ))); + .andExpect(status().isOk()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", nullValue())) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", nullValue())); } @Test @@ -4669,4 +4674,301 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration .andExpect(jsonPath("$._embedded.collection._embedded.adminGroup").doesNotExist()); } + + // TODO: remove ignore + @Test + @Ignore + public void uploadBitstreamWithoutAccessConditions() throws Exception { + context.turnOffAuthorisationSystem(); + Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build(); + WorkspaceItem wItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection).build(); + context.restoreAuthSystemState(); + + // prepare dummy bitstream + InputStream pdf = getClass().getResourceAsStream("simple-article.pdf"); + final MockMultipartFile pdfFile = new MockMultipartFile("file", "/local/path/simple-article.pdf", + "application/pdf", pdf); + + // auth + String authToken = getAuthToken(eperson.getEmail(), password); + + // upload file and verify response + getClient(authToken) + .perform(fileUpload("/api/submission/workspaceitems/" + wItem.getID()).file(pdfFile)) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))); + // TODO: currently no access conditions are created by default + + // verify that access conditions have been persisted + getClient(authToken) + .perform(get("/api/submission/workspaceitems/" + wItem.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))); + } + + // TODO: remove ignore + @Test + @Ignore + public void uploadBitstreamWithAccessConditionOpenAccess() throws Exception { + context.turnOffAuthorisationSystem(); + Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build(); + WorkspaceItem wItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection).build(); + context.restoreAuthSystemState(); + + // prepare dummy bitstream + InputStream pdf = getClass().getResourceAsStream("simple-article.pdf"); + final MockMultipartFile pdfFile = new MockMultipartFile("file", "/local/path/simple-article.pdf", + "application/pdf", pdf); + + // auth + String authToken = getAuthToken(eperson.getEmail(), password); + + // upload file and verify response + getClient(authToken) + .perform(fileUpload("/api/submission/workspaceitems/" + wItem.getID()) + .file(pdfFile) + // TODO: send access conditions with request + ) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))); + + // verify that access conditions have been persisted + getClient(authToken) + .perform(get("/api/submission/workspaceitems/" + wItem.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))); + } + + // TODO: all cases in 74236 that start with "upload a new bitstream" + + @Test + public void patchBitstreamWithAccessConditionOpenAccess() throws Exception { + context.turnOffAuthorisationSystem(); + Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build(); + InputStream pdf = getClass().getResourceAsStream("simple-article.pdf"); + WorkspaceItem wItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection) + .withFulltext("upload.pdf", "/local/path/simple-article.pdf", pdf) + .build(); + context.restoreAuthSystemState(); + + // auth + String authToken = getAuthToken(eperson.getEmail(), password); + + // perpare patch body + Map value = new HashMap<>(); + value.put("name", "openaccess"); + List ops = new ArrayList<>(); + ops.add(new AddOperation("/sections/upload/files/0/accessConditions/-", value)); + String patchBody = getPatchContent(ops); + + // submit patch and verify response + getClient(authToken) + .perform( + patch("/api/submission/workspaceitems/" + wItem.getID()) + .content(patchBody) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON) + ) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", nullValue())) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", nullValue())); + + // verify that access conditions have been persisted + getClient(authToken) + .perform(get("/api/submission/workspaceitems/" + wItem.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", nullValue())) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", nullValue())); + } + + @Test + public void patchBitstreamWithAccessConditionLeaseAndEndDate() throws Exception { + context.turnOffAuthorisationSystem(); + Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build(); + InputStream pdf = getClass().getResourceAsStream("simple-article.pdf"); + WorkspaceItem wItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection) + .withFulltext("upload.pdf", "/local/path/simple-article.pdf", pdf) + .build(); + context.restoreAuthSystemState(); + + // auth + String authToken = getAuthToken(eperson.getEmail(), password); + + // date + SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd"); + Date endDate = new Date(); + String endDateStr = dateFmt.format(endDate); + + // prepare patch body + Map accessCondition = new HashMap<>(); + accessCondition.put("name", "lease"); + accessCondition.put("endDate", endDateStr); + List ops = new ArrayList<>(); + ops.add(new AddOperation("/sections/upload/files/0/accessConditions/-", accessCondition)); + String patchBody = getPatchContent(ops); + + // submit patch and verify response + getClient(authToken) + .perform( + patch("/api/submission/workspaceitems/" + wItem.getID()) + .content(patchBody) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON) + ) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("lease"))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", nullValue())) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", is(endDateStr))); + + // verify that access conditions have been persisted + getClient(authToken) + .perform(get("/api/submission/workspaceitems/" + wItem.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("lease"))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", nullValue())) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", is(endDateStr))); + } + + @Test + public void patchBitstreamWithAccessConditionEmbargoAndStartDate() throws Exception { + context.turnOffAuthorisationSystem(); + Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build(); + InputStream pdf = getClass().getResourceAsStream("simple-article.pdf"); + WorkspaceItem wItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection) + .withFulltext("upload.pdf", "/local/path/simple-article.pdf", pdf) + .build(); + context.restoreAuthSystemState(); + + // auth + String authToken = getAuthToken(eperson.getEmail(), password); + + // date + SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd"); + Date startDate = DateUtils.addYears(new Date(), 4); + String startDateStr = dateFmt.format(startDate); + + // prepare patch body + Map accessCondition = new HashMap<>(); + accessCondition.put("name", "embargo"); + accessCondition.put("startDate", startDateStr); + List ops = new ArrayList<>(); + ops.add(new AddOperation("/sections/upload/files/0/accessConditions/-", accessCondition)); + String patchBody = getPatchContent(ops); + + // submit patch and verify response + getClient(authToken) + .perform( + patch("/api/submission/workspaceitems/" + wItem.getID()) + .content(patchBody) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON) + ) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("embargo"))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", is(startDateStr))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", nullValue())); + + // verify that access conditions have been persisted + getClient(authToken) + .perform(get("/api/submission/workspaceitems/" + wItem.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("embargo"))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", is(startDateStr))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", nullValue())); + } + + // TODO: remove ignore + @Test + @Ignore + public void patchBitstreamWithAccessConditionOpenAccessAndStartDate() throws Exception { + context.turnOffAuthorisationSystem(); + Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build(); + InputStream pdf = getClass().getResourceAsStream("simple-article.pdf"); + WorkspaceItem wItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection) + .withFulltext("upload.pdf", "/local/path/simple-article.pdf", pdf) + .build(); + context.restoreAuthSystemState(); + + // auth + String authToken = getAuthToken(eperson.getEmail(), password); + + // date + SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd"); + Date startDate = new Date(); + String startDateStr = dateFmt.format(startDate); + + // prepare patch body + Map accessCondition = new HashMap<>(); + accessCondition.put("name", "openaccess"); + accessCondition.put("startDate", startDateStr); + List ops = new ArrayList<>(); + ops.add(new AddOperation("/sections/upload/files/0/accessConditions/-", accessCondition)); + String patchBody = getPatchContent(ops); + + // submit patch and verify response + getClient(authToken) + .perform( + patch("/api/submission/workspaceitems/" + wItem.getID()) + .content(patchBody) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON) + ) + .andExpect(status().isInternalServerError()); + + // verify that access conditions have not been modified + // TODO: would be better if the initial access condition is not openaccess, but the builder does not seem to + // support that + getClient(authToken) + .perform(get("/api/submission/workspaceitems/" + wItem.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", nullValue())) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", nullValue())); + } + + // TODO: remove ignore + @Test + @Ignore + public void patchBitstreamWithAccessConditionLease() throws Exception { + context.turnOffAuthorisationSystem(); + Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build(); + InputStream pdf = getClass().getResourceAsStream("simple-article.pdf"); + WorkspaceItem wItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection) + .withFulltext("upload.pdf", "/local/path/simple-article.pdf", pdf) + .build(); + context.restoreAuthSystemState(); + + // auth + String authToken = getAuthToken(eperson.getEmail(), password); + + // prepare patch body + Map accessCondition = new HashMap<>(); + accessCondition.put("name", "lease"); + List ops = new ArrayList<>(); + ops.add(new AddOperation("/sections/upload/files/0/accessConditions/-", accessCondition)); + String patchBody = getPatchContent(ops); + + // submit patch and verify response + getClient(authToken) + .perform( + patch("/api/submission/workspaceitems/" + wItem.getID()) + .content(patchBody) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON) + ) + .andExpect(status().isInternalServerError()); + + // verify that access conditions have been persisted + getClient(authToken) + .perform(get("/api/submission/workspaceitems/" + wItem.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", nullValue())) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", nullValue())); + } + } From 16ae96b4c3d833c2a4acd1f05985d424c3a52bd7 Mon Sep 17 00:00:00 2001 From: Samuel Date: Tue, 26 Jan 2021 13:36:05 +0100 Subject: [PATCH 054/179] taskid 76191 Remove Traditional/Basic Workflow from codebase and database --- .../org/dspace/app/util/AuthorizeUtil.java | 4 +- .../main/java/org/dspace/curate/Curation.java | 9 +- .../curate/WorkflowCuratorServiceImpl.java | 422 ---- .../curate/factory/CurateServiceFactory.java | 27 - .../factory/CurateServiceFactoryImpl.java | 28 - .../service/WorkflowCuratorService.java | 76 - .../indexobject/IndexableWorkflowItem.java | 8 +- .../indexobject/ItemIndexFactoryImpl.java | 12 +- .../WorkflowItemIndexFactoryImpl.java | 20 +- .../factory/IndexObjectFactoryFactory.java | 4 +- .../factory/WorkflowItemIndexFactory.java | 4 +- .../dspace/eperson/EPersonServiceImpl.java | 73 +- .../eperson/service/EPersonService.java | 3 +- .../java/org/dspace/health/ItemCheck.java | 12 +- .../rdbms/DatabaseRegistryUpdater.java | 12 +- ...0_2018_04_03__Upgrade_Workflow_Policy.java | 26 +- ...4_11_04__Enable_XMLWorkflow_Migration.java | 17 +- ..._DS_2701_Enable_XMLWorkflow_Migration.java | 86 +- .../org/dspace/workflow/WorkflowItem.java | 123 +- .../dspace/workflow/WorkflowItemService.java | 94 +- .../WorkflowItemServiceImpl.java} | 84 +- .../org/dspace/workflow/WorkflowService.java | 100 +- .../factory/WorkflowServiceFactory.java | 21 + .../factory/WorkflowServiceFactoryImpl.java} | 27 +- .../java/org/dspace/workflow/package.html | 41 - .../workflowbasic/BasicWorkflowItem.java | 185 -- .../BasicWorkflowItemServiceImpl.java | 171 -- .../BasicWorkflowServiceImpl.java | 1256 ------------ .../dspace/workflowbasic/TaskListItem.java | 79 - .../TaskListItemServiceImpl.java | 69 - .../dao/BasicWorkflowItemDAO.java | 41 - .../workflowbasic/dao/TaskListItemDAO.java | 37 - .../dao/impl/BasicWorkflowItemDAOImpl.java | 105 - .../dao/impl/TaskListItemDAOImpl.java | 72 - .../factory/BasicWorkflowServiceFactory.java | 34 - .../BasicWorkflowServiceFactoryImpl.java | 57 - .../service/BasicWorkflowItemService.java | 40 - .../service/BasicWorkflowService.java | 206 -- .../service/TaskListItemService.java | 39 - .../java/org/dspace/xmlworkflow/Role.java | 4 +- .../WorkflowRequirementsServiceImpl.java | 28 +- ...viceImpl.java => WorkflowServiceImpl.java} | 72 +- .../org/dspace/xmlworkflow/WorkflowUtils.java | 6 +- .../factory/XmlWorkflowServiceFactory.java | 51 - .../service/WorkflowRequirementsService.java | 10 +- .../service/XmlWorkflowService.java | 79 - .../org/dspace/xmlworkflow/state/Step.java | 6 +- .../dspace/xmlworkflow/state/Workflow.java | 4 +- .../xmlworkflow/state/actions/Action.java | 10 +- .../AcceptEditRejectAction.java | 22 +- .../processingaction/FinalEditAction.java | 14 +- .../processingaction/ProcessingAction.java | 4 +- .../processingaction/ReviewAction.java | 22 +- .../ScoreEvaluationAction.java | 10 +- .../processingaction/ScoreReviewAction.java | 6 +- .../SelectReviewerAction.java | 6 +- .../SingleUserReviewAction.java | 22 +- .../actions/userassignment/AssignAction.java | 12 +- .../AssignOriginalSubmitterAction.java | 28 +- .../userassignment/AutoAssignAction.java | 18 +- .../actions/userassignment/ClaimAction.java | 30 +- .../userassignment/InheritUsersAction.java | 12 +- .../userassignment/NoUserSelectionAction.java | 12 +- .../userassignment/UserSelectionAction.java | 10 +- .../storedcomponents/ClaimedTask.java | 7 +- .../ClaimedTaskServiceImpl.java | 15 +- .../storedcomponents/InProgressUser.java | 7 +- .../InProgressUserServiceImpl.java | 9 +- .../storedcomponents/PoolTask.java | 9 +- .../storedcomponents/PoolTaskServiceImpl.java | 11 +- .../storedcomponents/WorkflowItemRole.java | 9 +- .../WorkflowItemRoleServiceImpl.java | 11 +- .../storedcomponents/XmlWorkflowItem.java | 141 -- .../storedcomponents/dao/ClaimedTaskDAO.java | 12 +- .../dao/InProgressUserDAO.java | 10 +- .../storedcomponents/dao/PoolTaskDAO.java | 8 +- ...kflowItemDAO.java => WorkflowItemDAO.java} | 20 +- .../dao/WorkflowItemRoleDAO.java | 6 +- .../dao/impl/ClaimedTaskDAOImpl.java | 12 +- .../dao/impl/InProgressUserDAOImpl.java | 10 +- .../dao/impl/PoolTaskDAOImpl.java | 8 +- .../dao/impl/WorkflowItemDAOImpl.java | 137 ++ .../dao/impl/WorkflowItemRoleDAOImpl.java | 6 +- .../dao/impl/XmlWorkflowItemDAOImpl.java | 137 -- .../service/ClaimedTaskService.java | 16 +- .../service/InProgressUserService.java | 10 +- .../service/PoolTaskService.java | 8 +- .../service/WorkflowItemRoleService.java | 8 +- .../service/XmlWorkflowItemService.java | 100 - ...V7.0_2021.01.22__Remove_basic_workflow.sql | 17 + ...V7.0_2021.01.22__Remove_basic_workflow.sql | 17 + ...V7.0_2021.01.22__Remove_basic_workflow.sql | 17 + .../org/dspace/builder/AbstractBuilder.java | 22 +- .../dspace/builder/ClaimedTaskBuilder.java | 10 +- .../org/dspace/builder/PoolTaskBuilder.java | 4 +- .../dspace/builder/WorkflowItemBuilder.java | 16 +- .../dspace/eperson/EPersonInWorkflowIT.java | 529 ++--- .../BasicWorkflowAuthorizationIT.java | 386 ---- .../BasicWorkflowAuthorizationRolesIT.java | 1711 ----------------- .../xmlworkflow/XmlWorkflowFactoryTest.java | 3 +- .../rest/converter/ClaimedTaskConverter.java | 4 +- .../app/rest/converter/PoolTaskConverter.java | 4 +- .../rest/converter/WorkflowItemConverter.java | 12 +- .../repository/ClaimedTaskRestRepository.java | 12 +- .../repository/PoolTaskRestRepository.java | 8 +- .../WorkflowItemRestRepository.java | 42 +- .../WorkflowItemStepLinkRepository.java | 16 +- ...PoolTaskRestPermissionEvaluatorPlugin.java | 4 +- ...WorkflowRestPermissionEvaluatorPlugin.java | 8 +- .../app/rest/submit/SubmissionService.java | 12 +- .../app/rest/DiscoveryRestControllerIT.java | 18 +- .../org/dspace/app/rest/LoginAsEPersonIT.java | 4 +- .../app/rest/StatisticsRestRepositoryIT.java | 5 +- .../app/rest/TaskRestRepositoriesIT.java | 110 +- .../rest/WorkflowActionRestRepositoryIT.java | 4 +- .../WorkflowDefinitionRestRepositoryIT.java | 4 +- .../rest/WorkflowItemRestRepositoryIT.java | 80 +- .../rest/WorkflowStepRestRepositoryIT.java | 4 +- .../eperson/DeleteEPersonSubmitterIT.java | 16 +- .../matcher/WorkflowDefinitionMatcher.java | 4 +- .../app/rest/matcher/WorkflowItemMatcher.java | 16 +- dspace/bin/dspace-info.pl | 22 +- dspace/config/hibernate.cfg.xml | 2 +- .../config/spring/api/core-dao-services.xml | 5 +- .../spring/api/core-factory-services.xml | 3 +- dspace/config/spring/api/core-services.xml | 7 +- dspace/config/spring/api/discovery.xml | 4 +- 127 files changed, 1448 insertions(+), 6663 deletions(-) delete mode 100644 dspace-api/src/main/java/org/dspace/curate/WorkflowCuratorServiceImpl.java delete mode 100644 dspace-api/src/main/java/org/dspace/curate/factory/CurateServiceFactory.java delete mode 100644 dspace-api/src/main/java/org/dspace/curate/factory/CurateServiceFactoryImpl.java delete mode 100644 dspace-api/src/main/java/org/dspace/curate/service/WorkflowCuratorService.java rename dspace-api/src/main/java/org/dspace/{xmlworkflow/storedcomponents/XmlWorkflowItemServiceImpl.java => workflow/WorkflowItemServiceImpl.java} (60%) rename dspace-api/src/main/java/org/dspace/{xmlworkflow/factory/XmlWorkflowServiceFactoryImpl.java => workflow/factory/WorkflowServiceFactoryImpl.java} (79%) delete mode 100644 dspace-api/src/main/java/org/dspace/workflow/package.html delete mode 100644 dspace-api/src/main/java/org/dspace/workflowbasic/BasicWorkflowItem.java delete mode 100644 dspace-api/src/main/java/org/dspace/workflowbasic/BasicWorkflowItemServiceImpl.java delete mode 100644 dspace-api/src/main/java/org/dspace/workflowbasic/BasicWorkflowServiceImpl.java delete mode 100644 dspace-api/src/main/java/org/dspace/workflowbasic/TaskListItem.java delete mode 100644 dspace-api/src/main/java/org/dspace/workflowbasic/TaskListItemServiceImpl.java delete mode 100644 dspace-api/src/main/java/org/dspace/workflowbasic/dao/BasicWorkflowItemDAO.java delete mode 100644 dspace-api/src/main/java/org/dspace/workflowbasic/dao/TaskListItemDAO.java delete mode 100644 dspace-api/src/main/java/org/dspace/workflowbasic/dao/impl/BasicWorkflowItemDAOImpl.java delete mode 100644 dspace-api/src/main/java/org/dspace/workflowbasic/dao/impl/TaskListItemDAOImpl.java delete mode 100644 dspace-api/src/main/java/org/dspace/workflowbasic/factory/BasicWorkflowServiceFactory.java delete mode 100644 dspace-api/src/main/java/org/dspace/workflowbasic/factory/BasicWorkflowServiceFactoryImpl.java delete mode 100644 dspace-api/src/main/java/org/dspace/workflowbasic/service/BasicWorkflowItemService.java delete mode 100644 dspace-api/src/main/java/org/dspace/workflowbasic/service/BasicWorkflowService.java delete mode 100644 dspace-api/src/main/java/org/dspace/workflowbasic/service/TaskListItemService.java rename dspace-api/src/main/java/org/dspace/xmlworkflow/{XmlWorkflowServiceImpl.java => WorkflowServiceImpl.java} (94%) delete mode 100644 dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactory.java delete mode 100644 dspace-api/src/main/java/org/dspace/xmlworkflow/service/XmlWorkflowService.java delete mode 100644 dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItem.java rename dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/{XmlWorkflowItemDAO.java => WorkflowItemDAO.java} (72%) create mode 100644 dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemDAOImpl.java delete mode 100644 dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/XmlWorkflowItemDAOImpl.java delete mode 100644 dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/XmlWorkflowItemService.java create mode 100644 dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.01.22__Remove_basic_workflow.sql create mode 100644 dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.01.22__Remove_basic_workflow.sql create mode 100644 dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.01.22__Remove_basic_workflow.sql delete mode 100644 dspace-api/src/test/java/org/dspace/workflowbasic/BasicWorkflowAuthorizationIT.java delete mode 100644 dspace-api/src/test/java/org/dspace/workflowbasic/BasicWorkflowAuthorizationRolesIT.java diff --git a/dspace-api/src/main/java/org/dspace/app/util/AuthorizeUtil.java b/dspace-api/src/main/java/org/dspace/app/util/AuthorizeUtil.java index efd813d29b..005db65d19 100644 --- a/dspace-api/src/main/java/org/dspace/app/util/AuthorizeUtil.java +++ b/dspace-api/src/main/java/org/dspace/app/util/AuthorizeUtil.java @@ -35,7 +35,7 @@ import org.dspace.eperson.factory.EPersonServiceFactory; import org.dspace.eperson.service.GroupService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.utils.DSpace; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.storedcomponents.CollectionRole; import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService; @@ -566,7 +566,7 @@ public class AuthorizeUtil { public static void authorizeManageGroup(Context context, Group group) throws SQLException, AuthorizeException { AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService(); GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - CollectionRoleService collectionRoleService = XmlWorkflowServiceFactory.getInstance() + CollectionRoleService collectionRoleService = WorkflowServiceFactory.getInstance() .getCollectionRoleService(); if (authorizeService.isAdmin(context)) { return; diff --git a/dspace-api/src/main/java/org/dspace/curate/Curation.java b/dspace-api/src/main/java/org/dspace/curate/Curation.java index 44cbb24ed9..4fcb580b0f 100644 --- a/dspace-api/src/main/java/org/dspace/curate/Curation.java +++ b/dspace-api/src/main/java/org/dspace/curate/Curation.java @@ -29,7 +29,6 @@ import org.dspace.content.DSpaceObject; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.core.Context; import org.dspace.core.factory.CoreServiceFactory; -import org.dspace.curate.factory.CurateServiceFactory; import org.dspace.eperson.EPerson; import org.dspace.eperson.factory.EPersonServiceFactory; import org.dspace.eperson.service.EPersonService; @@ -160,13 +159,7 @@ public class Curation extends DSpaceRunnable { } curator.curate(context, entry.getObjectId()); } else { - // make eperson who queued task the effective user - EPerson agent = ePersonService.findByEmail(context, entry.getEpersonId()); - if (agent != null) { - context.setCurrentUser(agent); - } - CurateServiceFactory.getInstance().getWorkflowCuratorService() - .curate(curator, context, entry.getObjectId()); + throw new IllegalArgumentException("curation for workflow items is no longer supported"); } } queue.release(this.queue, ticket, true); diff --git a/dspace-api/src/main/java/org/dspace/curate/WorkflowCuratorServiceImpl.java b/dspace-api/src/main/java/org/dspace/curate/WorkflowCuratorServiceImpl.java deleted file mode 100644 index a3a7b64afd..0000000000 --- a/dspace-api/src/main/java/org/dspace/curate/WorkflowCuratorServiceImpl.java +++ /dev/null @@ -1,422 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.curate; - -import static javax.xml.stream.XMLStreamConstants.CHARACTERS; -import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; -import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; - -import org.apache.logging.log4j.Logger; -import org.dspace.authorize.AuthorizeException; -import org.dspace.content.Collection; -import org.dspace.content.Item; -import org.dspace.content.service.CollectionService; -import org.dspace.core.Context; -import org.dspace.core.LogManager; -import org.dspace.core.factory.CoreServiceFactory; -import org.dspace.core.service.PluginService; -import org.dspace.curate.service.WorkflowCuratorService; -import org.dspace.eperson.EPerson; -import org.dspace.eperson.Group; -import org.dspace.eperson.service.EPersonService; -import org.dspace.eperson.service.GroupService; -import org.dspace.services.ConfigurationService; -import org.dspace.workflow.factory.WorkflowServiceFactory; -import org.dspace.workflowbasic.BasicWorkflowItem; -import org.dspace.workflowbasic.BasicWorkflowServiceImpl; -import org.dspace.workflowbasic.service.BasicWorkflowItemService; -import org.dspace.workflowbasic.service.BasicWorkflowService; -import org.springframework.beans.factory.annotation.Autowired; - -// Warning - static import ahead! - - -/** - * WorkflowCurator manages interactions between curation and workflow. - * Specifically, it is invoked in WorkflowManager to allow the - * performance of curation tasks during workflow. - * - * @author richardrodgers - */ -public class WorkflowCuratorServiceImpl implements WorkflowCuratorService { - - /** - * Logging category - */ - private static final Logger log - = org.apache.logging.log4j.LogManager.getLogger(); - - protected Map tsMap = new HashMap(); - - protected final String[] flowSteps = {"step1", "step2", "step3", "archive"}; - - @Autowired(required = true) - protected CollectionService collectionService; - @Autowired(required = true) - protected EPersonService ePersonService; - @Autowired(required = true) - protected GroupService groupService; - protected BasicWorkflowItemService basicWorkflowItemService; - protected BasicWorkflowService basicWorkflowService; - @Autowired(required = true) - protected WorkflowServiceFactory workflowServiceFactory; - @Autowired(required = true) - protected ConfigurationService configurationService; - - /** - * Initialize the bean (after dependency injection has already taken place). - * Ensures the configurationService is injected, so that we can read the - * settings from configuration - * Called by "init-method" in Spring config. - * - * @throws Exception ... - */ - public void init() throws Exception { - File cfgFile = new File(configurationService.getProperty("dspace.dir") + - File.separator + "config" + File.separator + - "workflow-curation.xml"); - try { - loadTaskConfig(cfgFile); - if (workflowServiceFactory.getWorkflowService() instanceof BasicWorkflowItemService) { - basicWorkflowService = (BasicWorkflowService) workflowServiceFactory.getWorkflowService(); - basicWorkflowItemService = (BasicWorkflowItemService) workflowServiceFactory.getWorkflowItemService(); - } - } catch (IOException e) { - // debug e.printStackTrace(); - log.fatal("Unable to load config: " + cfgFile.getAbsolutePath()); - } - } - - protected WorkflowCuratorServiceImpl() { - - } - - @Override - public boolean needsCuration(BasicWorkflowItem wfi) { - return getFlowStep(wfi) != null; - } - - @Override - public boolean doCuration(Context c, BasicWorkflowItem wfi) - throws AuthorizeException, IOException, SQLException { - FlowStep step = getFlowStep(wfi); - if (step != null) { - Curator curator = new Curator(); - // are we going to perform, or just put on queue? - if (step.queue != null) { - // The queue runner will call setReporter - for (Task task : step.tasks) { - curator.addTask(task.name); - } - curator.queue(c, String.valueOf(wfi.getID()), step.queue); - basicWorkflowItemService.update(c, wfi); - return false; - } else { - PluginService plugins = CoreServiceFactory.getInstance() - .getPluginService(); - try (Reporter reporter - = (Reporter) plugins - .getSinglePlugin(Reporter.class);) { - curator.setReporter(reporter); - boolean status = curate(curator, c, wfi); - reporter.close(); - return status; - } catch (Exception e) { - log.error("Failed to close report", e); - } - } - } - return true; - } - - - @Override - public boolean curate(Curator curator, Context c, String wfId) - throws AuthorizeException, IOException, SQLException { - BasicWorkflowItem wfi = basicWorkflowItemService.find(c, Integer.parseInt(wfId)); - if (wfi != null) { - if (curate(curator, c, wfi)) { - basicWorkflowService.advance(c, wfi, c.getCurrentUser(), false, true); - return true; - } - } else { - log.warn(LogManager.getHeader(c, "No workflow item found for id: " + wfId, null)); - } - return false; - } - - @Override - public boolean curate(Curator curator, Context c, BasicWorkflowItem wfi) - throws AuthorizeException, IOException, SQLException { - FlowStep step = getFlowStep(wfi); - if (step != null) { - // assign collection to item in case task needs it - Item item = wfi.getItem(); - item.setOwningCollection(wfi.getCollection()); - for (Task task : step.tasks) { - curator.addTask(task.name); - curator.curate(item); - int status = curator.getStatus(task.name); - String result = curator.getResult(task.name); - String action = "none"; - if (status == Curator.CURATE_FAIL) { - // task failed - notify any contacts the task has assigned - if (task.powers.contains("reject")) { - action = "reject"; - } - notifyContacts(c, wfi, task, "fail", action, result); - // if task so empowered, reject submission and terminate - if ("reject".equals(action)) { - basicWorkflowService.sendWorkflowItemBackSubmission(c, wfi, c.getCurrentUser(), - null, task.name + ": " + result); - return false; - } - } else if (status == Curator.CURATE_SUCCESS) { - if (task.powers.contains("approve")) { - action = "approve"; - } - notifyContacts(c, wfi, task, "success", action, result); - if ("approve".equals(action)) { - // cease further task processing and advance submission - return true; - } - } else if (status == Curator.CURATE_ERROR) { - notifyContacts(c, wfi, task, "error", action, result); - } - curator.clear(); - } - } - return true; - } - - protected void notifyContacts(Context c, BasicWorkflowItem wfi, Task task, - String status, String action, String message) - throws AuthorizeException, IOException, SQLException { - List epa = resolveContacts(c, task.getContacts(status), wfi); - if (epa.size() > 0) { - basicWorkflowService.notifyOfCuration(c, wfi, epa, task.name, action, message); - } - } - - protected List resolveContacts(Context c, List contacts, - BasicWorkflowItem wfi) - throws AuthorizeException, IOException, SQLException { - List epList = new ArrayList(); - for (String contact : contacts) { - // decode contacts - if ("$flowgroup".equals(contact)) { - // special literal for current flowgoup - int step = state2step(wfi.getState()); - // make sure this step exists - if (step < 4) { - Group wfGroup = collectionService.getWorkflowGroup(c, wfi.getCollection(), step); - if (wfGroup != null) { - epList.addAll(groupService.allMembers(c, wfGroup)); - } - } - } else if ("$colladmin".equals(contact)) { - Group adGroup = wfi.getCollection().getAdministrators(); - if (adGroup != null) { - epList.addAll(groupService.allMembers(c, adGroup)); - } - } else if ("$siteadmin".equals(contact)) { - EPerson siteEp = ePersonService.findByEmail(c, - configurationService.getProperty("mail.admin")); - if (siteEp != null) { - epList.add(siteEp); - } - } else if (contact.indexOf("@") > 0) { - // little shaky heuristic here - assume an eperson email name - EPerson ep = ePersonService.findByEmail(c, contact); - if (ep != null) { - epList.add(ep); - } - } else { - // assume it is an arbitrary group name - Group group = groupService.findByName(c, contact); - if (group != null) { - epList.addAll(groupService.allMembers(c, group)); - } - } - } - return epList; - } - - protected FlowStep getFlowStep(BasicWorkflowItem wfi) { - Collection coll = wfi.getCollection(); - String key = tsMap.containsKey(coll.getHandle()) ? coll.getHandle() : "default"; - TaskSet ts = tsMap.get(key); - if (ts != null) { - int myStep = state2step(wfi.getState()); - for (FlowStep fstep : ts.steps) { - if (fstep.step == myStep) { - return fstep; - } - } - } - return null; - } - - protected int state2step(int state) { - if (state <= BasicWorkflowServiceImpl.WFSTATE_STEP1POOL) { - return 1; - } - if (state <= BasicWorkflowServiceImpl.WFSTATE_STEP2POOL) { - return 2; - } - if (state <= BasicWorkflowServiceImpl.WFSTATE_STEP3POOL) { - return 3; - } - return 4; - } - - protected int stepName2step(String name) { - for (int i = 0; i < flowSteps.length; i++) { - if (flowSteps[i].equals(name)) { - return i + 1; - } - } - // invalid stepName - log - log.warn("Invalid step: '" + name + "' provided"); - return -1; - } - - protected void loadTaskConfig(File cfgFile) throws IOException { - Map collMap = new HashMap(); - Map setMap = new HashMap(); - TaskSet taskSet = null; - FlowStep flowStep = null; - Task task = null; - String type = null; - try { - XMLInputFactory factory = XMLInputFactory.newInstance(); - XMLStreamReader reader = factory.createXMLStreamReader( - new FileInputStream(cfgFile), "UTF-8"); - while (reader.hasNext()) { - int event = reader.next(); - if (event == START_ELEMENT) { - String eName = reader.getLocalName(); - if ("mapping".equals(eName)) { - collMap.put(reader.getAttributeValue(0), - reader.getAttributeValue(1)); - } else if ("taskset".equals(eName)) { - taskSet = new TaskSet(reader.getAttributeValue(0)); - } else if ("flowstep".equals(eName)) { - int count = reader.getAttributeCount(); - String queue = (count == 2) ? - reader.getAttributeValue(1) : null; - flowStep = new FlowStep(reader.getAttributeValue(0), queue); - } else if ("task".equals(eName)) { - task = new Task(reader.getAttributeValue(0)); - } else if ("workflow".equals(eName)) { - type = "power"; - } else if ("notify".equals(eName)) { - type = reader.getAttributeValue(0); - } - } else if (event == CHARACTERS) { - if (task != null) { - if ("power".equals(type)) { - task.addPower(reader.getText()); - } else { - task.addContact(type, reader.getText()); - } - } - } else if (event == END_ELEMENT) { - String eName = reader.getLocalName(); - if ("task".equals(eName)) { - flowStep.addTask(task); - task = null; - } else if ("flowstep".equals(eName)) { - taskSet.addStep(flowStep); - } else if ("taskset".equals(eName)) { - setMap.put(taskSet.setName, taskSet); - } - } - } - reader.close(); - // stitch maps together - for (Map.Entry collEntry : collMap.entrySet()) { - if (!"none".equals(collEntry.getValue()) && setMap.containsKey(collEntry.getValue())) { - tsMap.put(collEntry.getKey(), setMap.get(collEntry.getValue())); - } - } - } catch (XMLStreamException xsE) { - throw new IOException(xsE.getMessage(), xsE); - } - } - - protected class TaskSet { - public String setName = null; - public List steps = null; - - public TaskSet(String setName) { - this.setName = setName; - steps = new ArrayList(); - } - - public void addStep(FlowStep step) { - steps.add(step); - } - } - - protected class FlowStep { - public int step = -1; - public String queue = null; - public List tasks = null; - - public FlowStep(String stepStr, String queueStr) { - this.step = stepName2step(stepStr); - this.queue = queueStr; - tasks = new ArrayList(); - } - - public void addTask(Task task) { - tasks.add(task); - } - } - - protected class Task { - public String name = null; - public List powers = new ArrayList(); - public Map> contacts = new HashMap>(); - - public Task(String name) { - this.name = name; - } - - public void addPower(String power) { - powers.add(power); - } - - public void addContact(String status, String contact) { - List sContacts = contacts.get(status); - if (sContacts == null) { - sContacts = new ArrayList(); - contacts.put(status, sContacts); - } - sContacts.add(contact); - } - - public List getContacts(String status) { - List ret = contacts.get(status); - return (ret != null) ? ret : new ArrayList(); - } - } -} diff --git a/dspace-api/src/main/java/org/dspace/curate/factory/CurateServiceFactory.java b/dspace-api/src/main/java/org/dspace/curate/factory/CurateServiceFactory.java deleted file mode 100644 index 2063979fd5..0000000000 --- a/dspace-api/src/main/java/org/dspace/curate/factory/CurateServiceFactory.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.curate.factory; - -import org.dspace.curate.service.WorkflowCuratorService; -import org.dspace.services.factory.DSpaceServicesFactory; - -/** - * Abstract factory to get services for the curate package, use CurateServiceFactory.getInstance() to retrieve an - * implementation - * - * @author kevinvandevelde at atmire.com - */ -public abstract class CurateServiceFactory { - - public abstract WorkflowCuratorService getWorkflowCuratorService(); - - public static CurateServiceFactory getInstance() { - return DSpaceServicesFactory.getInstance().getServiceManager() - .getServiceByName("curateServiceFactory", CurateServiceFactory.class); - } -} diff --git a/dspace-api/src/main/java/org/dspace/curate/factory/CurateServiceFactoryImpl.java b/dspace-api/src/main/java/org/dspace/curate/factory/CurateServiceFactoryImpl.java deleted file mode 100644 index ad2bca1238..0000000000 --- a/dspace-api/src/main/java/org/dspace/curate/factory/CurateServiceFactoryImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.curate.factory; - -import org.dspace.curate.service.WorkflowCuratorService; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * Factory implementation to get services for the curate package, use CurateServiceFactory.getInstance() to retrieve - * an implementation - * - * @author kevinvandevelde at atmire.com - */ -public class CurateServiceFactoryImpl extends CurateServiceFactory { - - @Autowired(required = true) - private WorkflowCuratorService workflowCurator; - - @Override - public WorkflowCuratorService getWorkflowCuratorService() { - return workflowCurator; - } -} diff --git a/dspace-api/src/main/java/org/dspace/curate/service/WorkflowCuratorService.java b/dspace-api/src/main/java/org/dspace/curate/service/WorkflowCuratorService.java deleted file mode 100644 index 9f62baf664..0000000000 --- a/dspace-api/src/main/java/org/dspace/curate/service/WorkflowCuratorService.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.curate.service; - -import java.io.IOException; -import java.sql.SQLException; - -import org.dspace.authorize.AuthorizeException; -import org.dspace.core.Context; -import org.dspace.curate.Curator; -import org.dspace.workflowbasic.BasicWorkflowItem; - -/** - * WorkflowCurator manages interactions between curation and workflow. - * Specifically, it is invoked in WorkflowManager to allow the - * performance of curation tasks during workflow. - * - * @author richardrodgers - */ -public interface WorkflowCuratorService { - - - public boolean needsCuration(BasicWorkflowItem wfi); - - /** - * Determines and executes curation on a Workflow item. - * - * @param c the context - * @param wfi the workflow item - * @return true if curation was completed or not required, - * false if tasks were queued for later completion, - * or item was rejected - * @throws AuthorizeException if authorization error - * @throws IOException if IO error - * @throws SQLException if database error - */ - public boolean doCuration(Context c, BasicWorkflowItem wfi) - throws AuthorizeException, IOException, SQLException; - - - /** - * Determines and executes curation of a Workflow item. - * - * @param curator the Curator object - * @param c the user context - * @param wfId the workflow id - * @return true if curation was completed or not required, - * false if no workflow item found for id - * or item was rejected - * @throws AuthorizeException if authorization error - * @throws IOException if IO error - * @throws SQLException if database error - */ - public boolean curate(Curator curator, Context c, String wfId) - throws AuthorizeException, IOException, SQLException; - - /** - * Determines and executes curation of a Workflow item. - * - * @param curator the Curator object - * @param c the user context - * @param wfi the workflow item - * @return true if curation was completed or not required, - * false if item was rejected - * @throws AuthorizeException if authorization error - * @throws IOException if IO error - * @throws SQLException if database error - */ - public boolean curate(Curator curator, Context c, BasicWorkflowItem wfi) - throws AuthorizeException, IOException, SQLException; -} diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexableWorkflowItem.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexableWorkflowItem.java index 016fec1bbb..744cb174fb 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexableWorkflowItem.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexableWorkflowItem.java @@ -7,17 +7,17 @@ */ package org.dspace.discovery.indexobject; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.workflow.WorkflowItem; /** * Workflow item implementation for the IndexableObject * @author Kevin Van de Velde (kevin at atmire dot com) */ -public class IndexableWorkflowItem extends IndexableInProgressSubmission { +public class IndexableWorkflowItem extends IndexableInProgressSubmission { - public static final String TYPE = XmlWorkflowItem.class.getSimpleName(); + public static final String TYPE = WorkflowItem.class.getSimpleName(); - public IndexableWorkflowItem(XmlWorkflowItem inProgressSubmission) { + public IndexableWorkflowItem(WorkflowItem inProgressSubmission) { super(inProgressSubmission); } diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java index 07948bb0c3..6922665d07 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java @@ -64,8 +64,8 @@ import org.dspace.handle.service.HandleService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.util.MultiFormatDateParser; import org.dspace.util.SolrUtils; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -91,7 +91,7 @@ public class ItemIndexFactoryImpl extends DSpaceObjectIndexFactoryImpl + extends InprogressSubmissionIndexFactoryImpl implements WorkflowItemIndexFactory { @Autowired - protected XmlWorkflowItemService workflowItemService; + protected WorkflowItemService workflowItemService; @Autowired protected ClaimedTaskService claimedTaskService; @Autowired @@ -48,7 +48,7 @@ public class WorkflowItemIndexFactoryImpl @Override public Iterator findAll(Context context) throws SQLException { - final Iterator workflowItems = workflowItemService.findAll(context).iterator(); + final Iterator workflowItems = workflowItemService.findAll(context).iterator(); return new Iterator() { @Override @@ -73,7 +73,7 @@ public class WorkflowItemIndexFactoryImpl throws SQLException, IOException { // Add the ID's, types and call the SolrServiceIndexPlugins final SolrInputDocument doc = super.buildDocument(context, indexableObject); - final XmlWorkflowItem workflowItem = indexableObject.getIndexedObject(); + final WorkflowItem workflowItem = indexableObject.getIndexedObject(); final Item item = workflowItem.getItem(); // Add the item metadata as configured List discoveryConfigurations = SearchUtils @@ -92,11 +92,11 @@ public class WorkflowItemIndexFactoryImpl @Override public boolean supports(Object object) { - return object instanceof XmlWorkflowItem; + return object instanceof WorkflowItem; } @Override - public List getIndexableObjects(Context context, XmlWorkflowItem object) throws SQLException { + public List getIndexableObjects(Context context, WorkflowItem object) throws SQLException { List results = new ArrayList<>(); results.add(new IndexableWorkflowItem(object)); @@ -115,7 +115,7 @@ public class WorkflowItemIndexFactoryImpl @Override public Optional findIndexableObject(Context context, String id) throws SQLException { - final XmlWorkflowItem xmlWorkflowItem = workflowItemService.find(context, Integer.parseInt(id)); - return xmlWorkflowItem == null ? Optional.empty() : Optional.of(new IndexableWorkflowItem(xmlWorkflowItem)); + final WorkflowItem workflowItem = workflowItemService.find(context, Integer.parseInt(id)); + return workflowItem == null ? Optional.empty() : Optional.of(new IndexableWorkflowItem(workflowItem)); } } \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/IndexObjectFactoryFactory.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/IndexObjectFactoryFactory.java index 1152dffbd3..cd8b481764 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/IndexObjectFactoryFactory.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/IndexObjectFactoryFactory.java @@ -15,9 +15,9 @@ import org.dspace.content.service.WorkspaceItemService; import org.dspace.core.Context; import org.dspace.discovery.IndexableObject; import org.dspace.services.factory.DSpaceServicesFactory; +import org.dspace.workflow.WorkflowItemService; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -29,7 +29,7 @@ public abstract class IndexObjectFactoryFactory { @Autowired protected WorkspaceItemService workspaceItemService; @Autowired - protected XmlWorkflowItemService xmlWorkflowItemService; + protected WorkflowItemService workflowItemService; @Autowired protected ClaimedTaskService claimedTaskService; @Autowired diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/WorkflowItemIndexFactory.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/WorkflowItemIndexFactory.java index 2a2f695ed8..78be29128f 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/WorkflowItemIndexFactory.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/WorkflowItemIndexFactory.java @@ -8,7 +8,7 @@ package org.dspace.discovery.indexobject.factory; import org.dspace.discovery.indexobject.IndexableWorkflowItem; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.workflow.WorkflowItem; /** * Factory interface for indexing/retrieving workflow items objects in the search core @@ -16,5 +16,5 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; * @author Kevin Van de Velde (kevin at atmire dot com) */ public interface WorkflowItemIndexFactory - extends InprogressSubmissionIndexFactory { + extends InprogressSubmissionIndexFactory { } \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java b/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java index d4f34344fb..edcf28a84c 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java @@ -49,26 +49,17 @@ import org.dspace.versioning.dao.VersionDAO; import org.dspace.versioning.factory.VersionServiceFactory; import org.dspace.versioning.service.VersionHistoryService; import org.dspace.versioning.service.VersioningService; +import org.dspace.workflow.WorkflowItemService; import org.dspace.workflow.WorkflowService; import org.dspace.workflow.factory.WorkflowServiceFactory; -import org.dspace.workflowbasic.BasicWorkflowItem; -import org.dspace.workflowbasic.BasicWorkflowServiceImpl; -import org.dspace.workflowbasic.factory.BasicWorkflowServiceFactory; -import org.dspace.workflowbasic.service.BasicWorkflowItemService; -import org.dspace.workflowbasic.service.BasicWorkflowService; -import org.dspace.workflowbasic.service.TaskListItemService; import org.dspace.xmlworkflow.WorkflowConfigurationException; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; -import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.CollectionRole; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -294,10 +285,6 @@ public class EPersonServiceImpl extends DSpaceObjectServiceImpl impleme if (constraintList.size() > 0) { // Check if the constraints we found should be deleted if (cascade) { - boolean isBasicFramework = WorkflowServiceFactory.getInstance().getWorkflowService() - instanceof BasicWorkflowService; - boolean isXmlFramework = WorkflowServiceFactory.getInstance().getWorkflowService() - instanceof XmlWorkflowService; Iterator constraintsIterator = constraintList.iterator(); while (constraintsIterator.hasNext()) { @@ -334,23 +321,21 @@ public class EPersonServiceImpl extends DSpaceObjectServiceImpl impleme itemService.update(context, item); } } - } else if (StringUtils.equals(tableName, "cwf_claimtask") && isXmlFramework) { + } else if (StringUtils.equals(tableName, "cwf_claimtask")) { // Unclaim all XmlWorkflow tasks - XmlWorkflowItemService xmlWorkflowItemService = XmlWorkflowServiceFactory - .getInstance().getXmlWorkflowItemService(); - ClaimedTaskService claimedTaskService = XmlWorkflowServiceFactory + WorkflowItemService workflowItemService = WorkflowServiceFactory + .getInstance().getWorkflowItemService(); + ClaimedTaskService claimedTaskService = WorkflowServiceFactory .getInstance().getClaimedTaskService(); - XmlWorkflowService xmlWorkflowService = XmlWorkflowServiceFactory - .getInstance().getXmlWorkflowService(); - WorkflowRequirementsService workflowRequirementsService = XmlWorkflowServiceFactory + WorkflowService workflowService = WorkflowServiceFactory + .getInstance().getWorkflowService(); + WorkflowRequirementsService workflowRequirementsService = WorkflowServiceFactory .getInstance().getWorkflowRequirementsService(); - List xmlWorkflowItems = xmlWorkflowItemService - .findBySubmitter(context, ePerson); List claimedTasks = claimedTaskService.findByEperson(context, ePerson); for (ClaimedTask task : claimedTasks) { - xmlWorkflowService.deleteClaimedTask(context, task.getWorkflowItem(), task); + workflowService.deleteClaimedTask(context, task.getWorkflowItem(), task); try { workflowRequirementsService.removeClaimedUser(context, task.getWorkflowItem(), @@ -362,45 +347,15 @@ public class EPersonServiceImpl extends DSpaceObjectServiceImpl impleme .singletonList(tableName))); } } - } else if (StringUtils.equals(tableName, "workflowitem") && isBasicFramework) { - // Remove basicWorkflow workflowitem and unclaim them - BasicWorkflowItemService basicWorkflowItemService = BasicWorkflowServiceFactory.getInstance() - .getBasicWorkflowItemService(); - BasicWorkflowService basicWorkflowService = BasicWorkflowServiceFactory.getInstance() - .getBasicWorkflowService(); - TaskListItemService taskListItemService = BasicWorkflowServiceFactory.getInstance() - .getTaskListItemService(); - List workflowItems = basicWorkflowItemService.findByOwner(context, ePerson); - for (BasicWorkflowItem workflowItem : workflowItems) { - int state = workflowItem.getState(); - // unclaim tasks that are in the pool. - if (state == BasicWorkflowServiceImpl.WFSTATE_STEP1 - || state == BasicWorkflowServiceImpl.WFSTATE_STEP2 - || state == BasicWorkflowServiceImpl.WFSTATE_STEP3) { - log.info(LogManager.getHeader(context, "unclaim_workflow", - "workflow_id=" + workflowItem.getID() + ", claiming EPerson is deleted")); - basicWorkflowService.unclaim(context, workflowItem, context.getCurrentUser()); - // remove the EPerson from the list of persons that can (re-)claim the task - // while we are doing it below, we must do this here as well as the previously - // unclaimed tasks was put back into pool and we do not know the order the tables - // are checked. - taskListItemService.deleteByWorkflowItemAndEPerson(context, workflowItem, ePerson); - } - } } else if (StringUtils.equals(tableName, "resourcepolicy")) { // we delete the EPerson, it won't need any rights anymore. authorizeService.removeAllEPersonPolicies(context, ePerson); - } else if (StringUtils.equals(tableName, "tasklistitem") && isBasicFramework) { - // remove EPerson from the list of EPersons that may claim some specific workflow tasks. - TaskListItemService taskListItemService = BasicWorkflowServiceFactory.getInstance() - .getTaskListItemService(); - taskListItemService.deleteByEPerson(context, ePerson); - } else if (StringUtils.equals(tableName, "cwf_pooltask") && isXmlFramework) { - PoolTaskService poolTaskService = XmlWorkflowServiceFactory.getInstance().getPoolTaskService(); + } else if (StringUtils.equals(tableName, "cwf_pooltask")) { + PoolTaskService poolTaskService = WorkflowServiceFactory.getInstance().getPoolTaskService(); poolTaskService.deleteByEperson(context, ePerson); - } else if (StringUtils.equals(tableName, "cwf_workflowitemrole") && isXmlFramework) { - WorkflowItemRoleService workflowItemRoleService = XmlWorkflowServiceFactory.getInstance() - .getWorkflowItemRoleService(); + } else if (StringUtils.equals(tableName, "cwf_workflowitemrole")) { + WorkflowItemRoleService workflowItemRoleService = WorkflowServiceFactory.getInstance() + .getWorkflowItemRoleService(); workflowItemRoleService.deleteByEPerson(context, ePerson); } else { log.warn("EPerson is referenced in table '" + tableName diff --git a/dspace-api/src/main/java/org/dspace/eperson/service/EPersonService.java b/dspace-api/src/main/java/org/dspace/eperson/service/EPersonService.java index 4102b532fe..6d2dd67d76 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/service/EPersonService.java +++ b/dspace-api/src/main/java/org/dspace/eperson/service/EPersonService.java @@ -227,8 +227,7 @@ public interface EPersonService extends DSpaceObjectService, DSpaceObje * EPersons. Called by delete() to determine whether the eperson can * actually be deleted. * - * An EPerson cannot be deleted if it exists in the item, workflowitem, or - * tasklistitem tables. + * An EPerson cannot be deleted if it exists in the item, resourcepolicy or workflow-related tables. * * @param context The relevant DSpace Context. * @param ePerson EPerson to find diff --git a/dspace-api/src/main/java/org/dspace/health/ItemCheck.java b/dspace-api/src/main/java/org/dspace/health/ItemCheck.java index 4971b486da..cc7802d792 100644 --- a/dspace-api/src/main/java/org/dspace/health/ItemCheck.java +++ b/dspace-api/src/main/java/org/dspace/health/ItemCheck.java @@ -33,8 +33,8 @@ import org.dspace.eperson.service.EPersonService; import org.dspace.eperson.service.GroupService; import org.dspace.handle.factory.HandleServiceFactory; import org.dspace.handle.service.HandleService; -import org.dspace.workflowbasic.factory.BasicWorkflowServiceFactory; -import org.dspace.workflowbasic.service.BasicWorkflowItemService; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.factory.WorkflowServiceFactory; /** * @author LINDAT/CLARIN dev team @@ -48,8 +48,8 @@ public class ItemCheck extends Check { private MetadataValueService metadataValueService = ContentServiceFactory.getInstance().getMetadataValueService(); private ItemService itemService = ContentServiceFactory.getInstance().getItemService(); private WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); - private BasicWorkflowItemService basicWorkflowItemService = - BasicWorkflowServiceFactory.getInstance().getBasicWorkflowItemService(); + private WorkflowItemService workflowItemService = + WorkflowServiceFactory.getInstance().getWorkflowItemService(); private HandleService handleService = HandleServiceFactory.getInstance().getHandleService(); private EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); private GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); @@ -95,7 +95,7 @@ public class ItemCheck extends Check { ret += String.format( "\tWaiting for approval (workflow items): %d\n", - basicWorkflowItemService.countTotal(context)); + workflowItemService.countAll(context)); } catch (SQLException e) { error(e); @@ -132,7 +132,7 @@ public class ItemCheck extends Check { sb.append(String.format("Count %-14s: %s\n", "Group", String.valueOf(groupService.countTotal(context)))); sb.append(String.format("Count %-14s: %s\n", "BasicWorkflowItem", - String.valueOf(basicWorkflowItemService.countTotal(context)))); + String.valueOf(workflowItemService.countAll(context)))); sb.append(String.format("Count %-14s: %s\n", "WorkspaceItem", String.valueOf(workspaceItemService.countTotal(context)))); return sb.toString(); diff --git a/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseRegistryUpdater.java b/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseRegistryUpdater.java index 74653d8996..f52d6ef2a4 100644 --- a/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseRegistryUpdater.java +++ b/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseRegistryUpdater.java @@ -21,8 +21,6 @@ import org.dspace.content.NonUniqueMetadataException; import org.dspace.core.Context; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; -import org.dspace.workflow.factory.WorkflowServiceFactory; -import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.flywaydb.core.api.callback.Callback; import org.flywaydb.core.api.callback.Event; import org.slf4j.Logger; @@ -80,13 +78,9 @@ public class DatabaseRegistryUpdater implements Callback { MetadataImporter.loadRegistry(base + namespaceFile, true); } - // Check if XML Workflow is enabled in workflow.cfg - if (WorkflowServiceFactory.getInstance().getWorkflowService() instanceof XmlWorkflowService) { - // If so, load in the workflow metadata types as well - String workflowTypes = "workflow-types.xml"; - log.info("Reading {}", workflowTypes); - MetadataImporter.loadRegistry(base + workflowTypes, true); - } + String workflowTypes = "workflow-types.xml"; + log.info("Reading {}", workflowTypes); + MetadataImporter.loadRegistry(base + workflowTypes, true); context.restoreAuthSystemState(); // Commit changes and close context diff --git a/dspace-api/src/main/java/org/dspace/storage/rdbms/migration/V7_0_2018_04_03__Upgrade_Workflow_Policy.java b/dspace-api/src/main/java/org/dspace/storage/rdbms/migration/V7_0_2018_04_03__Upgrade_Workflow_Policy.java index 3da7f8b40f..6c336aa7de 100644 --- a/dspace-api/src/main/java/org/dspace/storage/rdbms/migration/V7_0_2018_04_03__Upgrade_Workflow_Policy.java +++ b/dspace-api/src/main/java/org/dspace/storage/rdbms/migration/V7_0_2018_04_03__Upgrade_Workflow_Policy.java @@ -8,8 +8,6 @@ package org.dspace.storage.rdbms.migration; import org.dspace.storage.rdbms.DatabaseUtils; -import org.dspace.workflow.factory.WorkflowServiceFactory; -import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.flywaydb.core.api.migration.BaseJavaMigration; import org.flywaydb.core.api.migration.Context; @@ -26,24 +24,20 @@ public class V7_0_2018_04_03__Upgrade_Workflow_Policy extends BaseJavaMigration @Override public void migrate(Context context) throws Exception { - // Make sure XML Workflow is enabled, shouldn't even be needed since this class is only loaded if the service - // is enabled. - if (WorkflowServiceFactory.getInstance().getWorkflowService() instanceof XmlWorkflowService) { - // Now, check if the XMLWorkflow table (cwf_workflowitem) already exists in this database - if (DatabaseUtils.tableExists(context.getConnection(), "cwf_workflowitem")) { - String dbtype = DatabaseUtils.getDbType(context.getConnection()); + // Check if the XMLWorkflow table (cwf_workflowitem) already exists in this database + if (DatabaseUtils.tableExists(context.getConnection(), "cwf_workflowitem")) { + String dbtype = DatabaseUtils.getDbType(context.getConnection()); - String sqlMigrationPath = "org/dspace/storage/rdbms/sqlmigration/workflow/" + dbtype + "/"; - String dataMigrateSQL = MigrationUtils.getResourceAsString( + String sqlMigrationPath = "org/dspace/storage/rdbms/sqlmigration/workflow/" + dbtype + "/"; + String dataMigrateSQL = MigrationUtils.getResourceAsString( sqlMigrationPath + "xmlworkflow/V7.0_2018.04.03__upgrade_workflow_policy.sql"); - // Actually execute the Data migration SQL - // This will migrate all existing traditional workflows to the new XMLWorkflow system & tables - DatabaseUtils.executeSql(context.getConnection(), dataMigrateSQL); + // Actually execute the Data migration SQL + // This will migrate all existing traditional workflows to the new XMLWorkflow system & tables + DatabaseUtils.executeSql(context.getConnection(), dataMigrateSQL); - // Assuming both succeeded, save the size of the scripts for getChecksum() below - migration_file_size = dataMigrateSQL.length(); - } + // Assuming both succeeded, save the size of the scripts for getChecksum() below + migration_file_size = dataMigrateSQL.length(); } } diff --git a/dspace-api/src/main/java/org/dspace/storage/rdbms/xmlworkflow/V5_0_2014_11_04__Enable_XMLWorkflow_Migration.java b/dspace-api/src/main/java/org/dspace/storage/rdbms/xmlworkflow/V5_0_2014_11_04__Enable_XMLWorkflow_Migration.java index dc8c7c22df..b3306a9fc9 100644 --- a/dspace-api/src/main/java/org/dspace/storage/rdbms/xmlworkflow/V5_0_2014_11_04__Enable_XMLWorkflow_Migration.java +++ b/dspace-api/src/main/java/org/dspace/storage/rdbms/xmlworkflow/V5_0_2014_11_04__Enable_XMLWorkflow_Migration.java @@ -12,8 +12,6 @@ import java.sql.SQLException; import org.dspace.storage.rdbms.DatabaseUtils; import org.dspace.storage.rdbms.migration.MigrationUtils; -import org.dspace.workflow.factory.WorkflowServiceFactory; -import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.flywaydb.core.api.migration.BaseJavaMigration; import org.flywaydb.core.api.migration.Context; import org.slf4j.Logger; @@ -55,15 +53,12 @@ public class V5_0_2014_11_04__Enable_XMLWorkflow_Migration @Override public void migrate(Context context) throws IOException, SQLException { - // Make sure XML Workflow is enabled, shouldn't even be needed since this class is only loaded if the service - // is enabled. - if (WorkflowServiceFactory.getInstance().getWorkflowService() instanceof XmlWorkflowService - // If your database was upgraded to DSpace 6 prior to enabling XML Workflow, we MUST skip this 5.x - // migration, as it is incompatible - // with a 6.x database. In that scenario the corresponding 6.x XML Workflow migration will create - // necessary tables. - && DatabaseUtils.getCurrentFlywayDSpaceState(context.getConnection()) < 6) { - // Now, check if the XMLWorkflow table (cwf_workflowitem) already exists in this database + // If your database was upgraded to DSpace 6 prior to enabling XML Workflow, we MUST skip this 5.x + // migration, as it is incompatible + // with a 6.x database. In that scenario the corresponding 6.x XML Workflow migration will create + // necessary tables. + if (DatabaseUtils.getCurrentFlywayDSpaceState(context.getConnection()) < 6) { + // Check if the XMLWorkflow table (cwf_workflowitem) already exists in this database // If XMLWorkflow Table does NOT exist in this database, then lets do the migration! // If XMLWorkflow Table ALREADY exists, then this migration is a noop, we assume you manually ran the sql // scripts diff --git a/dspace-api/src/main/java/org/dspace/storage/rdbms/xmlworkflow/V6_0_2015_09_01__DS_2701_Enable_XMLWorkflow_Migration.java b/dspace-api/src/main/java/org/dspace/storage/rdbms/xmlworkflow/V6_0_2015_09_01__DS_2701_Enable_XMLWorkflow_Migration.java index b70b19f3a5..9aa0f4877c 100644 --- a/dspace-api/src/main/java/org/dspace/storage/rdbms/xmlworkflow/V6_0_2015_09_01__DS_2701_Enable_XMLWorkflow_Migration.java +++ b/dspace-api/src/main/java/org/dspace/storage/rdbms/xmlworkflow/V6_0_2015_09_01__DS_2701_Enable_XMLWorkflow_Migration.java @@ -10,8 +10,6 @@ package org.dspace.storage.rdbms.xmlworkflow; import org.dspace.storage.rdbms.DatabaseUtils; import org.dspace.storage.rdbms.migration.MigrationUtils; -import org.dspace.workflow.factory.WorkflowServiceFactory; -import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.flywaydb.core.api.migration.BaseJavaMigration; import org.flywaydb.core.api.migration.Context; @@ -39,51 +37,47 @@ public class V6_0_2015_09_01__DS_2701_Enable_XMLWorkflow_Migration extends BaseJ @Override public void migrate(Context context) throws Exception { - // Make sure XML Workflow is enabled, shouldn't even be needed since this class is only loaded if the service - // is enabled. - if (WorkflowServiceFactory.getInstance().getWorkflowService() instanceof XmlWorkflowService) { - // Now, check if the XMLWorkflow table (cwf_workflowitem) already exists in this database - // If XMLWorkflow Table does NOT exist in this database, then lets do the migration! - // If XMLWorkflow Table ALREADY exists, then this migration is a noop, we assume you manually ran the sql - // scripts - if (!DatabaseUtils.tableExists(context.getConnection(), "cwf_workflowitem")) { - String dbtype = context.getConnection().getMetaData().getDatabaseProductName(); - String dbFileLocation = null; - if (dbtype.toLowerCase().contains("postgres")) { - dbFileLocation = "postgres"; - } else if (dbtype.toLowerCase().contains("oracle")) { - dbFileLocation = "oracle"; - } else if (dbtype.toLowerCase().contains("h2")) { - dbFileLocation = "h2"; - } - - - // Determine path of this migration class (as the SQL scripts - // we will run are based on this path under /src/main/resources) - String packagePath = V6_0_2015_09_01__DS_2701_Enable_XMLWorkflow_Migration.class.getPackage().getName() - .replace(".", "/"); - - // Get the contents of our DB Schema migration script, based on path & DB type - // (e.g. /src/main/resources/[path-to-this-class]/postgres/xml_workflow_migration.sql) - String dbMigrateSQL = MigrationUtils.getResourceAsString(packagePath + "/" + dbFileLocation + - "/v6.0__DS-2701_xml_workflow_migration.sql"); - - // Actually execute the Database schema migration SQL - // This will create the necessary tables for the XMLWorkflow feature - DatabaseUtils.executeSql(context.getConnection(), dbMigrateSQL); - - // Get the contents of our data migration script, based on path & DB type - // (e.g. /src/main/resources/[path-to-this-class]/postgres/data_workflow_migration.sql) - String dataMigrateSQL = MigrationUtils.getResourceAsString(packagePath + "/" + dbFileLocation + - "/v6.0__DS-2701_data_workflow_migration.sql"); - - // Actually execute the Data migration SQL - // This will migrate all existing traditional workflows to the new XMLWorkflow system & tables - DatabaseUtils.executeSql(context.getConnection(), dataMigrateSQL); - - // Assuming both succeeded, save the size of the scripts for getChecksum() below - migration_file_size = dbMigrateSQL.length() + dataMigrateSQL.length(); + // Check if the XMLWorkflow table (cwf_workflowitem) already exists in this database + // If XMLWorkflow Table does NOT exist in this database, then lets do the migration! + // If XMLWorkflow Table ALREADY exists, then this migration is a noop, we assume you manually ran the sql + // scripts + if (!DatabaseUtils.tableExists(context.getConnection(), "cwf_workflowitem")) { + String dbtype = context.getConnection().getMetaData().getDatabaseProductName(); + String dbFileLocation = null; + if (dbtype.toLowerCase().contains("postgres")) { + dbFileLocation = "postgres"; + } else if (dbtype.toLowerCase().contains("oracle")) { + dbFileLocation = "oracle"; + } else if (dbtype.toLowerCase().contains("h2")) { + dbFileLocation = "h2"; } + + + // Determine path of this migration class (as the SQL scripts + // we will run are based on this path under /src/main/resources) + String packagePath = V6_0_2015_09_01__DS_2701_Enable_XMLWorkflow_Migration.class.getPackage().getName() + .replace(".", "/"); + + // Get the contents of our DB Schema migration script, based on path & DB type + // (e.g. /src/main/resources/[path-to-this-class]/postgres/xml_workflow_migration.sql) + String dbMigrateSQL = MigrationUtils.getResourceAsString(packagePath + "/" + dbFileLocation + + "/v6.0__DS-2701_xml_workflow_migration.sql"); + + // Actually execute the Database schema migration SQL + // This will create the necessary tables for the XMLWorkflow feature + DatabaseUtils.executeSql(context.getConnection(), dbMigrateSQL); + + // Get the contents of our data migration script, based on path & DB type + // (e.g. /src/main/resources/[path-to-this-class]/postgres/data_workflow_migration.sql) + String dataMigrateSQL = MigrationUtils.getResourceAsString(packagePath + "/" + dbFileLocation + + "/v6.0__DS-2701_data_workflow_migration.sql"); + + // Actually execute the Data migration SQL + // This will migrate all existing traditional workflows to the new XMLWorkflow system & tables + DatabaseUtils.executeSql(context.getConnection(), dataMigrateSQL); + + // Assuming both succeeded, save the size of the scripts for getChecksum() below + migration_file_size = dbMigrateSQL.length() + dataMigrateSQL.length(); } } diff --git a/dspace-api/src/main/java/org/dspace/workflow/WorkflowItem.java b/dspace-api/src/main/java/org/dspace/workflow/WorkflowItem.java index e3d5ccde9a..9780f15d72 100644 --- a/dspace-api/src/main/java/org/dspace/workflow/WorkflowItem.java +++ b/dspace-api/src/main/java/org/dspace/workflow/WorkflowItem.java @@ -7,13 +7,128 @@ */ package org.dspace.workflow; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + +import org.dspace.content.Collection; import org.dspace.content.InProgressSubmission; +import org.dspace.content.Item; +import org.dspace.core.Context; +import org.dspace.eperson.EPerson; /** - * Interface representing a workflowitem, each workflowItem implementation must implement this interface. + * Class representing an item going through the workflow process in DSpace * - * @author kevinvandevelde at atmire.com + * @author Bram De Schouwer (bram.deschouwer at dot com) + * @author Kevin Van de Velde (kevin at atmire dot com) + * @author Ben Bosman (ben at atmire dot com) + * @author Mark Diggory (markd at atmire dot com) */ -public interface WorkflowItem extends InProgressSubmission { - public int getState(); +@Entity +@Table(name = "cwf_workflowitem") +public class WorkflowItem implements InProgressSubmission { + + @Id + @Column(name = "workflowitem_id") + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "cwf_workflowitem_seq") + @SequenceGenerator(name = "cwf_workflowitem_seq", sequenceName = "cwf_workflowitem_seq", allocationSize = 1) + private Integer id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "collection_id") + private Collection collection; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "item_id", unique = true) + private Item item; + + @Column(name = "multiple_titles") + private boolean multipleTitles = false; + + @Column(name = "published_before") + private boolean publishedBefore = false; + + @Column(name = "multiple_files") + private boolean multipleFiles = false; + + /** + * Protected constructor, create object using: + * {@link WorkflowItemService#create(Context, Item, Collection)} + */ + protected WorkflowItem() { + + } + + /** + * Get the internal ID of this workflow item + * + * @return the internal identifier + */ + @Override + public Integer getID() { + return id; + } + + + @Override + public Collection getCollection() { + return this.collection; + } + + public void setCollection(Collection collection) { + this.collection = collection; + } + + @Override + public Item getItem() { + return item; + } + + public void setItem(Item item) { + this.item = item; + } + + @Override + public EPerson getSubmitter() { + return item.getSubmitter(); + } + + @Override + public boolean hasMultipleFiles() { + return multipleFiles; + } + + @Override + public void setMultipleFiles(boolean b) { + this.multipleFiles = b; + } + + @Override + public boolean hasMultipleTitles() { + return this.multipleTitles; + } + + @Override + public void setMultipleTitles(boolean b) { + this.multipleTitles = b; + } + + @Override + public boolean isPublishedBefore() { + return this.publishedBefore; + } + + @Override + public void setPublishedBefore(boolean b) { + this.publishedBefore = b; + } } diff --git a/dspace-api/src/main/java/org/dspace/workflow/WorkflowItemService.java b/dspace-api/src/main/java/org/dspace/workflow/WorkflowItemService.java index 48ee20b9ad..5327b55515 100644 --- a/dspace-api/src/main/java/org/dspace/workflow/WorkflowItemService.java +++ b/dspace-api/src/main/java/org/dspace/workflow/WorkflowItemService.java @@ -26,9 +26,10 @@ import org.dspace.eperson.EPerson; * * @author kevinvandevelde at atmire.com */ -public interface WorkflowItemService extends InProgressSubmissionService { +public interface WorkflowItemService extends InProgressSubmissionService { - public T create(Context context, Item item, Collection collection) throws SQLException, AuthorizeException; + public WorkflowItem create(Context context, Item item, Collection collection) throws SQLException, + AuthorizeException; /** * Get a workflow item from the database. @@ -38,7 +39,7 @@ public interface WorkflowItemService extends InProgressS * @return the workflow item, or null if the ID is invalid. * @throws SQLException An exception that provides information on a database access error or other errors. */ - public T find(Context context, int id) throws SQLException; + public WorkflowItem find(Context context, int id) throws SQLException; /** * return all workflowitems @@ -47,7 +48,7 @@ public interface WorkflowItemService extends InProgressS * @return List of all workflowItems in system * @throws SQLException An exception that provides information on a database access error or other errors. */ - public List findAll(Context context) throws SQLException; + public List findAll(Context context) throws SQLException; /** * Get all workflow items for a particular collection. @@ -57,7 +58,7 @@ public interface WorkflowItemService extends InProgressS * @return array of the corresponding workflow items * @throws SQLException An exception that provides information on a database access error or other errors. */ - public List findByCollection(Context context, Collection collection) throws SQLException; + public List findByCollection(Context context, Collection collection) throws SQLException; /** * Check to see if a particular item is currently under Workflow. @@ -68,7 +69,7 @@ public interface WorkflowItemService extends InProgressS * @return workflow item corresponding to the item, or null * @throws SQLException An exception that provides information on a database access error or other errors. */ - public T findByItem(Context context, Item item) throws SQLException; + public WorkflowItem findByItem(Context context, Item item) throws SQLException; /** * Get all workflow items that were original submissions by a particular @@ -79,7 +80,7 @@ public interface WorkflowItemService extends InProgressS * @return the corresponding workflow items * @throws SQLException An exception that provides information on a database access error or other errors. */ - public List findBySubmitter(Context context, EPerson ep) throws SQLException; + public List findBySubmitter(Context context, EPerson ep) throws SQLException; /** * Delete all workflow items present in the specified collection. @@ -89,10 +90,10 @@ public interface WorkflowItemService extends InProgressS * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. * @throws SQLException An exception that provides information on a database access error or other errors. * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. + * to perform a particular action. */ public void deleteByCollection(Context context, Collection collection) - throws SQLException, IOException, AuthorizeException; + throws SQLException, IOException, AuthorizeException; /** * Delete the specified workflow item. @@ -104,6 +105,79 @@ public interface WorkflowItemService extends InProgressS * @throws AuthorizeException Exception indicating the current user of the context does not have permission * to perform a particular action. */ - public void delete(Context context, T workflowItem) throws SQLException, AuthorizeException, IOException; + public void delete(Context context, WorkflowItem workflowItem) + throws SQLException, AuthorizeException, IOException; + + /** + * return all workflowitems for a certain page + * + * @param context The relevant DSpace Context. + * @param page paging: page number + * @param pagesize paging: items per page + * @return WorkflowItem list of all the workflow items in system + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + public List findAll(Context context, Integer page, Integer pagesize) throws SQLException; + + /** + * return all workflowitems for a certain page with a certain collection + * + * @param context The relevant DSpace Context. + * @param page paging: page number + * @param pagesize paging: items per page + * @param collection restrict to this collection + * @return WorkflowItem list of all the workflow items in system + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + public List findAllInCollection(Context context, Integer page, Integer pagesize, + Collection collection) throws SQLException; + + /** + * return how many workflow items appear in the database + * + * @param context The relevant DSpace Context. + * @return the number of workflow items + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + public int countAll(Context context) throws SQLException; + + /** + * return how many workflow items that appear in the collection + * + * @param context The relevant DSpace Context. + * @param collection restrict to this collection + * @return the number of workflow items + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + public int countAllInCollection(Context context, Collection collection) throws SQLException; + + /** + * Return all the workflow items from a specific submitter respecting the pagination parameters + * + * @param context + * The relevant DSpace Context. + * @param ep + * the eperson that has submitted the item + * @param pageNumber + * paging: page number + * @param pageSize + * paging: items per page + * @return + * @throws SQLException + */ + public List findBySubmitter(Context context, EPerson ep, Integer pageNumber, Integer pageSize) + throws SQLException; + + /** + * Count the number of workflow items from a specific submitter + * + * @param context + * The relevant DSpace Context. + * @param ep + * the eperson that has submitted the item + * @return + * @throws SQLException + */ + public int countBySubmitter(Context context, EPerson ep) throws SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/workflow/WorkflowItemServiceImpl.java similarity index 60% rename from dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItemServiceImpl.java rename to dspace-api/src/main/java/org/dspace/workflow/WorkflowItemServiceImpl.java index 010c310ba6..7743d7f501 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/workflow/WorkflowItemServiceImpl.java @@ -5,7 +5,7 @@ * * http://www.dspace.org/license/ */ -package org.dspace.xmlworkflow.storedcomponents; +package org.dspace.workflow; import java.io.IOException; import java.sql.SQLException; @@ -21,24 +21,24 @@ import org.dspace.core.Context; import org.dspace.core.LogManager; import org.dspace.eperson.EPerson; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; -import org.dspace.xmlworkflow.storedcomponents.dao.XmlWorkflowItemDAO; +import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; +import org.dspace.xmlworkflow.storedcomponents.dao.WorkflowItemDAO; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** - * Service implementation for the XmlWorkflowItem object. - * This class is responsible for all business logic calls for the XmlWorkflowItem object and is autowired by spring. + * Service implementation for the WorkflowItem object. + * This class is responsible for all business logic calls for the WorkflowItem object and is autowired by spring. * This class should never be accessed directly. * * @author kevinvandevelde at atmire.com */ -public class XmlWorkflowItemServiceImpl implements XmlWorkflowItemService { +public class WorkflowItemServiceImpl implements WorkflowItemService { @Autowired(required = true) - protected XmlWorkflowItemDAO xmlWorkflowItemDAO; + protected WorkflowItemDAO workflowItemDAO; @Autowired(required = true) @@ -55,25 +55,25 @@ public class XmlWorkflowItemServiceImpl implements XmlWorkflowItemService { /* * The current step in the workflow system in which this workflow item is present */ - private Logger log = org.apache.logging.log4j.LogManager.getLogger(XmlWorkflowItemServiceImpl.class); + private Logger log = org.apache.logging.log4j.LogManager.getLogger(WorkflowItemServiceImpl.class); - protected XmlWorkflowItemServiceImpl() { + protected WorkflowItemServiceImpl() { } @Override - public XmlWorkflowItem create(Context context, Item item, Collection collection) + public WorkflowItem create(Context context, Item item, Collection collection) throws SQLException, AuthorizeException { - XmlWorkflowItem xmlWorkflowItem = xmlWorkflowItemDAO.create(context, new XmlWorkflowItem()); - xmlWorkflowItem.setItem(item); - xmlWorkflowItem.setCollection(collection); - return xmlWorkflowItem; + WorkflowItem workflowItem = workflowItemDAO.create(context, new WorkflowItem()); + workflowItem.setItem(item); + workflowItem.setCollection(collection); + return workflowItem; } @Override - public XmlWorkflowItem find(Context context, int id) throws SQLException { - XmlWorkflowItem workflowItem = xmlWorkflowItemDAO.findByID(context, XmlWorkflowItem.class, id); + public WorkflowItem find(Context context, int id) throws SQLException { + WorkflowItem workflowItem = workflowItemDAO.findByID(context, WorkflowItem.class, id); if (workflowItem == null) { if (log.isDebugEnabled()) { @@ -90,69 +90,69 @@ public class XmlWorkflowItemServiceImpl implements XmlWorkflowItemService { } @Override - public List findAll(Context context) throws SQLException { - return xmlWorkflowItemDAO.findAll(context, XmlWorkflowItem.class); + public List findAll(Context context) throws SQLException { + return workflowItemDAO.findAll(context, WorkflowItem.class); } @Override - public List findAll(Context context, Integer page, Integer pagesize) throws SQLException { + public List findAll(Context context, Integer page, Integer pagesize) throws SQLException { return findAllInCollection(context, page, pagesize, null); } @Override - public List findAllInCollection(Context context, Integer page, Integer pagesize, - Collection collection) throws SQLException { + public List findAllInCollection(Context context, Integer page, Integer pagesize, + Collection collection) throws SQLException { Integer offset = null; if (page != null && pagesize != null) { offset = page * pagesize; } - return xmlWorkflowItemDAO.findAllInCollection(context, offset, pagesize, collection); + return workflowItemDAO.findAllInCollection(context, offset, pagesize, collection); } @Override public int countAll(Context context) throws SQLException { - return xmlWorkflowItemDAO.countAll(context); + return workflowItemDAO.countAll(context); } @Override public int countAllInCollection(Context context, Collection collection) throws SQLException { - return xmlWorkflowItemDAO.countAllInCollection(context, collection); + return workflowItemDAO.countAllInCollection(context, collection); } @Override - public List findBySubmitter(Context context, EPerson ep) throws SQLException { - return xmlWorkflowItemDAO.findBySubmitter(context, ep); + public List findBySubmitter(Context context, EPerson ep) throws SQLException { + return workflowItemDAO.findBySubmitter(context, ep); } @Override - public List findBySubmitter(Context context, EPerson ep, Integer pageNumber, Integer pageSize) + public List findBySubmitter(Context context, EPerson ep, Integer pageNumber, Integer pageSize) throws SQLException { Integer offset = null; if (pageNumber != null && pageSize != null) { offset = pageNumber * pageSize; } - return xmlWorkflowItemDAO.findBySubmitter(context, ep, pageNumber, pageSize); + return workflowItemDAO.findBySubmitter(context, ep, pageNumber, pageSize); } @Override public int countBySubmitter(Context context, EPerson ep) throws SQLException { - return xmlWorkflowItemDAO.countBySubmitter(context, ep); + return workflowItemDAO.countBySubmitter(context, ep); } @Override public void deleteByCollection(Context context, Collection collection) throws SQLException, IOException, AuthorizeException { - List xmlWorkflowItems = findByCollection(context, collection); - Iterator iterator = xmlWorkflowItems.iterator(); + List workflowItems = findByCollection(context, collection); + Iterator iterator = workflowItems.iterator(); while (iterator.hasNext()) { - XmlWorkflowItem workflowItem = iterator.next(); + WorkflowItem workflowItem = iterator.next(); iterator.remove(); delete(context, workflowItem); } } @Override - public void delete(Context context, XmlWorkflowItem workflowItem) + public void delete(Context context, WorkflowItem workflowItem) throws SQLException, AuthorizeException, IOException { Item item = workflowItem.getItem(); // Need to delete the workspaceitem row first since it refers @@ -164,17 +164,17 @@ public class XmlWorkflowItemServiceImpl implements XmlWorkflowItemService { } @Override - public List findByCollection(Context context, Collection collection) throws SQLException { - return xmlWorkflowItemDAO.findByCollection(context, collection); + public List findByCollection(Context context, Collection collection) throws SQLException { + return workflowItemDAO.findByCollection(context, collection); } @Override - public XmlWorkflowItem findByItem(Context context, Item item) throws SQLException { - return xmlWorkflowItemDAO.findByItem(context, item); + public WorkflowItem findByItem(Context context, Item item) throws SQLException { + return workflowItemDAO.findByItem(context, item); } @Override - public void update(Context context, XmlWorkflowItem workflowItem) throws SQLException, AuthorizeException { + public void update(Context context, WorkflowItem workflowItem) throws SQLException, AuthorizeException { // FIXME check auth log.info(LogManager.getHeader(context, "update_workflow_item", "workflowitem_id=" + workflowItem.getID())); @@ -182,11 +182,11 @@ public class XmlWorkflowItemServiceImpl implements XmlWorkflowItemService { // Update the item itemService.update(context, workflowItem.getItem()); - xmlWorkflowItemDAO.save(context, workflowItem); + workflowItemDAO.save(context, workflowItem); } @Override - public void deleteWrapper(Context context, XmlWorkflowItem workflowItem) throws SQLException, AuthorizeException { + public void deleteWrapper(Context context, WorkflowItem workflowItem) throws SQLException, AuthorizeException { List roles = workflowItemRoleService.findByWorkflowItem(context, workflowItem); Iterator workflowItemRoleIterator = roles.iterator(); while (workflowItemRoleIterator.hasNext()) { @@ -200,12 +200,12 @@ public class XmlWorkflowItemServiceImpl implements XmlWorkflowItemService { claimedTaskService.deleteByWorkflowItem(context, workflowItem); // FIXME - auth? - xmlWorkflowItemDAO.delete(context, workflowItem); + workflowItemDAO.delete(context, workflowItem); } @Override - public void move(Context context, XmlWorkflowItem inProgressSubmission, Collection fromCollection, + public void move(Context context, WorkflowItem inProgressSubmission, Collection fromCollection, Collection toCollection) { // TODO not implemented yet } diff --git a/dspace-api/src/main/java/org/dspace/workflow/WorkflowService.java b/dspace-api/src/main/java/org/dspace/workflow/WorkflowService.java index ced074d71d..62cb355dbe 100644 --- a/dspace-api/src/main/java/org/dspace/workflow/WorkflowService.java +++ b/dspace-api/src/main/java/org/dspace/workflow/WorkflowService.java @@ -10,27 +10,37 @@ package org.dspace.workflow; import java.io.IOException; import java.sql.SQLException; import java.util.List; +import javax.mail.MessagingException; +import javax.servlet.http.HttpServletRequest; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Collection; +import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; +import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; +import org.dspace.xmlworkflow.state.Step; +import org.dspace.xmlworkflow.state.Workflow; +import org.dspace.xmlworkflow.state.actions.ActionResult; +import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; +import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; +import org.dspace.xmlworkflow.storedcomponents.PoolTask; /** - * Service interface class for the WorkflowService framework. - * All WorkflowServices service classes should implement this class since it offers some basic methods which all - * Workflows - * are required to have. + * When an item is submitted and is somewhere in a workflow, it has a row in the + * cwf_workflowitem table pointing to it. * - * @param some implementation of workflow item. - * @author kevinvandevelde at atmire.com + * Once the item has completed the workflow it will be archived + * + * @author Bram De Schouwer (bram.deschouwer at dot com) + * @author Kevin Van de Velde (kevin at atmire dot com) + * @author Ben Bosman (ben at atmire dot com) + * @author Mark Diggory (markd at atmire dot com) */ -public interface WorkflowService { - - +public interface WorkflowService { /** * startWorkflow() begins a workflow - in a single transaction do away with * the PersonalWorkspace entry and turn it into a WorkflowItem. @@ -40,12 +50,12 @@ public interface WorkflowService { * @return The resulting workflow item * @throws SQLException An exception that provides information on a database access error or other errors. * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. + * to perform a particular action. * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. * @throws WorkflowException if workflow error */ - public T start(Context context, WorkspaceItem wsi) - throws SQLException, AuthorizeException, IOException, WorkflowException; + public WorkflowItem start(Context context, WorkspaceItem wsi) + throws SQLException, AuthorizeException, IOException, WorkflowException; /** * startWithoutNotify() starts the workflow normally, but disables @@ -57,12 +67,12 @@ public interface WorkflowService { * @return the resulting workflow item. * @throws SQLException An exception that provides information on a database access error or other errors. * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. + * to perform a particular action. * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. * @throws WorkflowException if workflow error */ - public T startWithoutNotify(Context c, WorkspaceItem wsi) - throws SQLException, AuthorizeException, IOException, WorkflowException; + public WorkflowItem startWithoutNotify(Context c, WorkspaceItem wsi) + throws SQLException, AuthorizeException, IOException, WorkflowException; /** * abort() aborts a workflow, completely deleting it (administrator do this) @@ -75,10 +85,11 @@ public interface WorkflowService { * @return workspace item returned to workspace * @throws SQLException An exception that provides information on a database access error or other errors. * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. + * to perform a particular action. * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. */ - public WorkspaceItem abort(Context c, T wi, EPerson e) throws SQLException, AuthorizeException, IOException; + public WorkspaceItem abort(Context c, WorkflowItem wi, EPerson e) + throws SQLException, AuthorizeException, IOException; /** * Deletes workflow task item in correct order. @@ -88,39 +99,76 @@ public interface WorkflowService { * @param e Admin that deletes this workflow task and item (for logging * @throws SQLException An exception that provides information on a database access error or other errors. * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. + * to perform a particular action. * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. */ - public void deleteWorkflowByWorkflowItem(Context c, T wi, EPerson e) - throws SQLException, AuthorizeException, IOException; + public void deleteWorkflowByWorkflowItem(Context c, WorkflowItem wi, EPerson e) + throws SQLException, AuthorizeException, IOException; - public WorkspaceItem sendWorkflowItemBackSubmission(Context c, T workflowItem, EPerson e, String provenance, + public WorkspaceItem sendWorkflowItemBackSubmission(Context c, WorkflowItem workflowItem, EPerson e, + String provenance, String rejection_message) - throws SQLException, AuthorizeException, IOException; + throws SQLException, AuthorizeException, IOException; public String getMyDSpaceLink(); public void deleteCollection(Context context, Collection collection) - throws SQLException, IOException, AuthorizeException; + throws SQLException, IOException, AuthorizeException; public List getEPersonDeleteConstraints(Context context, EPerson ePerson) throws SQLException; public Group getWorkflowRoleGroup(Context context, Collection collection, String roleName, Group roleGroup) - throws SQLException, IOException, WorkflowConfigurationException, AuthorizeException, WorkflowException; + throws SQLException, IOException, WorkflowConfigurationException, AuthorizeException, WorkflowException; /** * This method will create the workflowRoleGroup for a collection and the given rolename * @param context The relevant DSpace context * @param collection The collection * @param roleName The rolename - * @return The created Group + * @return The created Group * @throws AuthorizeException If something goes wrong * @throws SQLException If something goes wrong * @throws IOException If something goes wrong * @throws WorkflowConfigurationException If something goes wrong */ public Group createWorkflowRoleGroup(Context context, Collection collection, String roleName) - throws AuthorizeException, SQLException, IOException, WorkflowConfigurationException; + throws AuthorizeException, SQLException, IOException, WorkflowConfigurationException; public List getFlywayMigrationLocations(); + + public void alertUsersOnTaskActivation(Context c, WorkflowItem wfi, String emailTemplate, List epa, + String... arguments) throws IOException, SQLException, MessagingException; + + public WorkflowActionConfig doState(Context c, EPerson user, HttpServletRequest request, int workflowItemId, + Workflow workflow, WorkflowActionConfig currentActionConfig) + throws SQLException, AuthorizeException, IOException, MessagingException, WorkflowException; + + public WorkflowActionConfig processOutcome(Context c, EPerson user, Workflow workflow, Step currentStep, + WorkflowActionConfig currentActionConfig, ActionResult currentOutcome, + WorkflowItem wfi, boolean enteredNewStep) + throws IOException, AuthorizeException, SQLException, WorkflowException; + + public void deleteAllTasks(Context context, WorkflowItem wi) throws SQLException, AuthorizeException; + + public void deleteAllPooledTasks(Context c, WorkflowItem wi) throws SQLException, AuthorizeException; + + public void deletePooledTask(Context context, WorkflowItem wi, PoolTask task) + throws SQLException, AuthorizeException; + + public void deleteClaimedTask(Context c, WorkflowItem wi, ClaimedTask task) + throws SQLException, AuthorizeException; + + public void createPoolTasks(Context context, WorkflowItem wi, RoleMembers assignees, Step step, + WorkflowActionConfig action) + throws SQLException, AuthorizeException; + + public void createOwnedTask(Context context, WorkflowItem wi, Step step, WorkflowActionConfig action, EPerson e) + throws SQLException, AuthorizeException; + + public void grantUserAllItemPolicies(Context context, Item item, EPerson epa, String actionType) + throws AuthorizeException, SQLException; + + public void removeUserItemPolicies(Context context, Item item, EPerson e) throws SQLException, AuthorizeException; + + public String getEPersonName(EPerson ePerson); } diff --git a/dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactory.java b/dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactory.java index b338e54f5a..f5bbdc8829 100644 --- a/dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactory.java +++ b/dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactory.java @@ -10,6 +10,13 @@ package org.dspace.workflow.factory; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.workflow.WorkflowItemService; import org.dspace.workflow.WorkflowService; +import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; +import org.dspace.xmlworkflow.service.WorkflowRequirementsService; +import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; +import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService; +import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService; +import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; +import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; /** * Abstract factory to get services for the workflow package, use WorkflowServiceFactory.getInstance() to retrieve an @@ -19,8 +26,22 @@ import org.dspace.workflow.WorkflowService; */ public abstract class WorkflowServiceFactory { + public abstract XmlWorkflowFactory getWorkflowFactory(); + + public abstract WorkflowRequirementsService getWorkflowRequirementsService(); + public abstract WorkflowService getWorkflowService(); + public abstract ClaimedTaskService getClaimedTaskService(); + + public abstract CollectionRoleService getCollectionRoleService(); + + public abstract InProgressUserService getInProgressUserService(); + + public abstract PoolTaskService getPoolTaskService(); + + public abstract WorkflowItemRoleService getWorkflowItemRoleService(); + public abstract WorkflowItemService getWorkflowItemService(); public static WorkflowServiceFactory getInstance() { diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactoryImpl.java b/dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactoryImpl.java similarity index 79% rename from dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactoryImpl.java rename to dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactoryImpl.java index 5f36285d86..a934819edf 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactoryImpl.java @@ -5,18 +5,17 @@ * * http://www.dspace.org/license/ */ -package org.dspace.xmlworkflow.factory; +package org.dspace.workflow.factory; import org.dspace.workflow.WorkflowItemService; import org.dspace.workflow.WorkflowService; +import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; -import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService; import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -25,14 +24,14 @@ import org.springframework.beans.factory.annotation.Autowired; * * @author kevinvandevelde at atmire.com */ -public class XmlWorkflowServiceFactoryImpl extends XmlWorkflowServiceFactory { +public class WorkflowServiceFactoryImpl extends WorkflowServiceFactory { @Autowired(required = true) private XmlWorkflowFactory workflowFactory; @Autowired(required = true) private WorkflowRequirementsService workflowRequirementsService; @Autowired(required = true) - private XmlWorkflowService xmlWorkflowService; + private WorkflowService workflowService; @Autowired(required = true) private ClaimedTaskService claimedTaskService; @Autowired(required = true) @@ -44,7 +43,7 @@ public class XmlWorkflowServiceFactoryImpl extends XmlWorkflowServiceFactory { @Autowired(required = true) private WorkflowItemRoleService workflowItemRoleService; @Autowired(required = true) - private XmlWorkflowItemService xmlWorkflowItemService; + private WorkflowItemService workflowItemService; @Override public XmlWorkflowFactory getWorkflowFactory() { @@ -57,8 +56,8 @@ public class XmlWorkflowServiceFactoryImpl extends XmlWorkflowServiceFactory { } @Override - public XmlWorkflowService getXmlWorkflowService() { - return xmlWorkflowService; + public WorkflowService getWorkflowService() { + return workflowService; } @Override @@ -86,18 +85,8 @@ public class XmlWorkflowServiceFactoryImpl extends XmlWorkflowServiceFactory { return workflowItemRoleService; } - @Override - public XmlWorkflowItemService getXmlWorkflowItemService() { - return xmlWorkflowItemService; - } - - @Override - public WorkflowService getWorkflowService() { - return getXmlWorkflowService(); - } - @Override public WorkflowItemService getWorkflowItemService() { - return getXmlWorkflowItemService(); + return workflowItemService; } } diff --git a/dspace-api/src/main/java/org/dspace/workflow/package.html b/dspace-api/src/main/java/org/dspace/workflow/package.html deleted file mode 100644 index 1cc217af71..0000000000 --- a/dspace-api/src/main/java/org/dspace/workflow/package.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - -

DSpace's workflow system

- -

-DSpace has a simple workflow system, which models the workflows -as 5 steps: SUBMIT, three intermediate steps (STEP1, STEP2, STEP3), and ARCHIVE. -When an item is submitted to DSpace, it is in the SUBMIT state. If there -are no intermediate states defined, then it proceeds directly to ARCHIVE and -is put into the main DSpace archive. -

- -

-EPerson groups may be assigned to the three possible intermediate steps, -where they are expected to act on the item at those steps. For example, -if a Collection's owners desire a review step, they would create a Group -of reviewers, and assign that Group to step 1. The members of step 1's -Group will receive emails asking them to review the submission, and -will need to perform an action on the item before it can be rejected -back to the submitter or placed in the archive. -

- - - diff --git a/dspace-api/src/main/java/org/dspace/workflowbasic/BasicWorkflowItem.java b/dspace-api/src/main/java/org/dspace/workflowbasic/BasicWorkflowItem.java deleted file mode 100644 index 065cae25fc..0000000000 --- a/dspace-api/src/main/java/org/dspace/workflowbasic/BasicWorkflowItem.java +++ /dev/null @@ -1,185 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.workflowbasic; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToOne; -import javax.persistence.SequenceGenerator; -import javax.persistence.Table; - -import org.dspace.content.Collection; -import org.dspace.content.Item; -import org.dspace.core.Context; -import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; - -/** - * Class representing an item going through the workflow process in DSpace - * - * @author Robert Tansley - * @version $Revision$ - */ -@Entity -@Table(name = "workflowitem") -public class BasicWorkflowItem implements WorkflowItem { - - @Id - @Column(name = "workflow_id", unique = true, nullable = false) - @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "workflowitem_seq") - @SequenceGenerator(name = "workflowitem_seq", sequenceName = "workflowitem_seq", allocationSize = 1) - private Integer workflowitemId; - - - /** - * The item this workflow object pertains to - */ - @OneToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "item_id", unique = true) - private Item item; - - /** - * The collection the item is being submitted to - */ - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "collection_id") - private Collection collection; - - /** - * EPerson owning the current state - */ - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "owner") - private EPerson owner; - - @Column(name = "state") - private int state; - - @Column(name = "multiple_titles") - private boolean multipleTitles = false; - - @Column(name = "published_before") - private boolean publishedBefore = false; - - @Column(name = "multiple_files") - private boolean multipleFiles = false; - - /** - * Protected constructor, create object using: - * {@link org.dspace.workflowbasic.service.BasicWorkflowItemService#create(Context, Item, Collection)} - */ - protected BasicWorkflowItem() { - - } - - /** - * Get the internal ID of this workflow item - * - * @return the internal identifier - */ - @Override - public Integer getID() { - return workflowitemId; - } - - /** - * get owner of WorkflowItem - * - * @return EPerson owner - */ - public EPerson getOwner() { - return owner; - } - - /** - * set owner of WorkflowItem - * - * @param ep owner - */ - public void setOwner(EPerson ep) { - this.owner = ep; - } - - /** - * Get state of WorkflowItem - * - * @return state - */ - public int getState() { - return state; - } - - /** - * Set state of WorkflowItem - * - * @param newstate new state (from WorkflowManager) - */ - public void setState(int newstate) { - this.state = newstate; - } - - // InProgressSubmission methods - @Override - public Item getItem() { - return item; - } - - void setItem(Item item) { - this.item = item; - } - - @Override - public Collection getCollection() { - return collection; - } - - public void setCollection(Collection collection) { - this.collection = collection; - } - - @Override - public EPerson getSubmitter() { - return item.getSubmitter(); - } - - @Override - public boolean hasMultipleFiles() { - return multipleFiles; - } - - @Override - public void setMultipleFiles(boolean b) { - this.multipleFiles = b; - } - - @Override - public boolean hasMultipleTitles() { - return multipleTitles; - } - - @Override - public void setMultipleTitles(boolean b) { - this.multipleTitles = b; - } - - @Override - public boolean isPublishedBefore() { - return publishedBefore; - } - - @Override - public void setPublishedBefore(boolean b) { - this.publishedBefore = b; - } -} diff --git a/dspace-api/src/main/java/org/dspace/workflowbasic/BasicWorkflowItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/workflowbasic/BasicWorkflowItemServiceImpl.java deleted file mode 100644 index 2751fd33e1..0000000000 --- a/dspace-api/src/main/java/org/dspace/workflowbasic/BasicWorkflowItemServiceImpl.java +++ /dev/null @@ -1,171 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.workflowbasic; - -import java.io.IOException; -import java.sql.SQLException; -import java.util.Iterator; -import java.util.List; - -import org.apache.logging.log4j.Logger; -import org.dspace.authorize.AuthorizeException; -import org.dspace.content.Collection; -import org.dspace.content.Item; -import org.dspace.content.service.ItemService; -import org.dspace.core.Context; -import org.dspace.core.LogManager; -import org.dspace.eperson.EPerson; -import org.dspace.workflowbasic.dao.BasicWorkflowItemDAO; -import org.dspace.workflowbasic.service.BasicWorkflowItemService; -import org.dspace.workflowbasic.service.TaskListItemService; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * Service implementation for the BasicWorkflowItem object. - * This class is responsible for all business logic calls for the BasicWorkflowItem object and is autowired by spring. - * This class should never be accessed directly. - * - * @author kevinvandevelde at atmire.com - */ -public class BasicWorkflowItemServiceImpl implements BasicWorkflowItemService { - - /** - * log4j category - */ - protected static Logger log = org.apache.logging.log4j.LogManager.getLogger(BasicWorkflowItem.class); - - @Autowired(required = true) - protected BasicWorkflowItemDAO workflowItemDAO; - - @Autowired(required = true) - protected ItemService itemService; - @Autowired(required = true) - protected TaskListItemService taskListItemService; - - - protected BasicWorkflowItemServiceImpl() { - - } - - @Override - public BasicWorkflowItem create(Context context, Item item, Collection collection) - throws SQLException, AuthorizeException { - if (findByItem(context, item) != null) { - throw new IllegalArgumentException( - "Unable to create a workflow item for an item that already has a workflow item."); - } - BasicWorkflowItem workflowItem = workflowItemDAO.create(context, new BasicWorkflowItem()); - workflowItem.setItem(item); - workflowItem.setCollection(collection); - update(context, workflowItem); - return workflowItem; - } - - @Override - public BasicWorkflowItem find(Context context, int id) throws SQLException { - BasicWorkflowItem workflowItem = workflowItemDAO.findByID(context, BasicWorkflowItem.class, id); - - if (workflowItem == null) { - if (log.isDebugEnabled()) { - log.debug(LogManager.getHeader(context, "find_workflow_item", - "not_found,workflow_id=" + id)); - } - } else { - if (log.isDebugEnabled()) { - log.debug(LogManager.getHeader(context, "find_workflow_item", - "workflow_id=" + id)); - } - } - return workflowItem; - } - - @Override - public List findAll(Context context) throws SQLException { - return workflowItemDAO.findAll(context, BasicWorkflowItem.class); - } - - @Override - public List findBySubmitter(Context context, EPerson ep) throws SQLException { - return workflowItemDAO.findBySubmitter(context, ep); - } - - @Override - public void deleteByCollection(Context context, Collection collection) - throws SQLException, IOException, AuthorizeException { - List workflowItems = findByCollection(context, collection); - Iterator iterator = workflowItems.iterator(); - while (iterator.hasNext()) { - BasicWorkflowItem workflowItem = iterator.next(); - iterator.remove(); - delete(context, workflowItem); - } - } - - @Override - public void delete(Context context, BasicWorkflowItem workflowItem) - throws SQLException, AuthorizeException, IOException { - Item item = workflowItem.getItem(); - deleteWrapper(context, workflowItem); - itemService.delete(context, item); - } - - @Override - public List findByCollection(Context context, Collection collection) throws SQLException { - return workflowItemDAO.findByCollection(context, collection); - } - - @Override - public BasicWorkflowItem findByItem(Context context, Item item) throws SQLException { - return workflowItemDAO.findByItem(context, item); - } - - @Override - public void deleteWrapper(Context context, BasicWorkflowItem workflowItem) throws SQLException, AuthorizeException { - // delete any pending tasks - taskListItemService.deleteByWorkflowItem(context, workflowItem); - - // FIXME - auth? - workflowItemDAO.delete(context, workflowItem); - } - - @Override - public void update(Context context, BasicWorkflowItem workflowItem) throws SQLException, AuthorizeException { - // FIXME check auth - log.info(LogManager.getHeader(context, "update_workflow_item", - "workflow_item_id=" + workflowItem.getID())); - - - // Update the item - itemService.update(context, workflowItem.getItem()); - - // Update ourselves - workflowItemDAO.save(context, workflowItem); - } - - @Override - public List findPooledTasks(Context context, EPerson ePerson) throws SQLException { - return workflowItemDAO.findByPooledTasks(context, ePerson); - } - - @Override - public List findByOwner(Context context, EPerson ePerson) throws SQLException { - return workflowItemDAO.findByOwner(context, ePerson); - } - - @Override - public int countTotal(Context context) throws SQLException { - return workflowItemDAO.countRows(context); - } - - @Override - public void move(Context context, BasicWorkflowItem inProgressSubmission, Collection fromCollection, - Collection toCollection) { - // TODO not implemented yet - - } -} diff --git a/dspace-api/src/main/java/org/dspace/workflowbasic/BasicWorkflowServiceImpl.java b/dspace-api/src/main/java/org/dspace/workflowbasic/BasicWorkflowServiceImpl.java deleted file mode 100644 index f97e5d9e4a..0000000000 --- a/dspace-api/src/main/java/org/dspace/workflowbasic/BasicWorkflowServiceImpl.java +++ /dev/null @@ -1,1256 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.workflowbasic; - -import java.io.IOException; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.MissingResourceException; -import java.util.ResourceBundle; -import java.util.UUID; -import javax.mail.MessagingException; - -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.Logger; -import org.dspace.authorize.AuthorizeException; -import org.dspace.authorize.ResourcePolicy; -import org.dspace.authorize.service.AuthorizeService; -import org.dspace.content.Bitstream; -import org.dspace.content.Bundle; -import org.dspace.content.Collection; -import org.dspace.content.DCDate; -import org.dspace.content.Item; -import org.dspace.content.MetadataSchemaEnum; -import org.dspace.content.WorkspaceItem; -import org.dspace.content.service.CollectionService; -import org.dspace.content.service.InstallItemService; -import org.dspace.content.service.ItemService; -import org.dspace.content.service.WorkspaceItemService; -import org.dspace.core.Constants; -import org.dspace.core.Context; -import org.dspace.core.Email; -import org.dspace.core.I18nUtil; -import org.dspace.core.LogManager; -import org.dspace.curate.service.WorkflowCuratorService; -import org.dspace.eperson.EPerson; -import org.dspace.eperson.Group; -import org.dspace.eperson.service.GroupService; -import org.dspace.handle.service.HandleService; -import org.dspace.services.ConfigurationService; -import org.dspace.services.factory.DSpaceServicesFactory; -import org.dspace.usage.UsageWorkflowEvent; -import org.dspace.workflowbasic.service.BasicWorkflowItemService; -import org.dspace.workflowbasic.service.BasicWorkflowService; -import org.dspace.workflowbasic.service.TaskListItemService; -import org.springframework.beans.factory.annotation.Autowired; - -public class BasicWorkflowServiceImpl implements BasicWorkflowService { - - @Autowired(required = true) - protected AuthorizeService authorizeService; - @Autowired(required = true) - protected CollectionService collectionService; - @Autowired(required = true) - protected GroupService groupService; - @Autowired(required = true) - protected HandleService handleService; - @Autowired(required = true) - protected InstallItemService installItemService; - @Autowired(required = true) - protected ItemService itemService; - @Autowired(required = true) - protected TaskListItemService taskListItemService; - @Autowired(required = true) - protected WorkflowCuratorService workflowCuratorService; - @Autowired(required = true) - protected BasicWorkflowItemService workflowItemService; - @Autowired(required = true) - protected WorkspaceItemService workspaceItemService; - @Autowired(required = true) - protected ConfigurationService configurationService; - - protected BasicWorkflowServiceImpl() { - - } - - /** - * Symbolic names of workflow steps. - */ - protected final String workflowText[] = { - "SUBMIT", // 0 - "STEP1POOL", // 1 - "STEP1", // 2 - "STEP2POOL", // 3 - "STEP2", // 4 - "STEP3POOL", // 5 - "STEP3", // 6 - "ARCHIVE" // 7 - }; - - /* support for 'no notification' */ - protected Map noEMail = new HashMap<>(); - - /** - * log4j logger - */ - private final Logger log = org.apache.logging.log4j.LogManager.getLogger(BasicWorkflowServiceImpl.class); - - @Override - public int getWorkflowID(String state) { - for (int i = 0; i < workflowText.length; ++i) { - if (state.equalsIgnoreCase(workflowText[i])) { - return i; - } - } - return -1; - } - - /** - * This methods grants the appropriate permissions to reviewers so that they - * can read and edit metadata and read files and edit files if allowed by - * configuration. - * In most cases this method must be called within a try-finally-block that - * temporary disables the authentication system. This is not done by this - * method as it should be done carefully and only in contexts in which - * granting the permissions is authorized by some previous checks. - * - * @param context - * @param wfi While all policies are granted on item, bundle or bitstream - * level, this method takes an workflowitem for convenience and - * uses wfi.getItem() to get the actual item. - * @param reviewer EPerson to grant the rights to. - * @throws SQLException - * @throws AuthorizeException - */ - protected void grantReviewerPolicies(Context context, BasicWorkflowItem wfi, EPerson reviewer) - throws SQLException, AuthorizeException { - if (reviewer == null) { - return; - } - - // get item and bundle "ORIGINAL" - Item item = wfi.getItem(); - Bundle originalBundle; - try { - originalBundle = itemService.getBundles(item, "ORIGINAL").get(0); - } catch (IndexOutOfBoundsException ex) { - originalBundle = null; - } - - // grant item level policies - for (int action : - new int[] {Constants.READ, Constants.WRITE, Constants.ADD, Constants.REMOVE, Constants.DELETE}) { - authorizeService.addPolicy(context, item, action, reviewer, ResourcePolicy.TYPE_WORKFLOW); - } - - // set bitstream and bundle policies - if (originalBundle != null) { - authorizeService.addPolicy(context, originalBundle, Constants.READ, reviewer, ResourcePolicy.TYPE_WORKFLOW); - - // shall reviewers be able to edit files? - boolean editFiles = configurationService.getBooleanProperty("workflow.reviewer.file-edit", false); - // if a reviewer should be able to edit bitstreams, we need add - // permissions regarding the bundle "ORIGINAL" and its bitstreams - if (editFiles) { - authorizeService - .addPolicy(context, originalBundle, Constants.ADD, reviewer, ResourcePolicy.TYPE_WORKFLOW); - authorizeService - .addPolicy(context, originalBundle, Constants.REMOVE, reviewer, ResourcePolicy.TYPE_WORKFLOW); - // Whenever a new bitstream is added, it inherit the policies of the bundle. - // So we need to add all policies newly created bitstreams should get. - authorizeService - .addPolicy(context, originalBundle, Constants.WRITE, reviewer, ResourcePolicy.TYPE_WORKFLOW); - authorizeService - .addPolicy(context, originalBundle, Constants.DELETE, reviewer, ResourcePolicy.TYPE_WORKFLOW); - } - for (Bitstream bitstream : originalBundle.getBitstreams()) { - authorizeService.addPolicy(context, bitstream, Constants.READ, reviewer, ResourcePolicy.TYPE_WORKFLOW); - - // add further rights if reviewer should be able to edit bitstreams - if (editFiles) { - authorizeService - .addPolicy(context, bitstream, Constants.WRITE, reviewer, ResourcePolicy.TYPE_WORKFLOW); - authorizeService - .addPolicy(context, bitstream, Constants.DELETE, reviewer, ResourcePolicy.TYPE_WORKFLOW); - } - } - } - } - - /** - * This methods revokes any permission granted by the basic workflow systems - * on the item specified as attribute. At time of writing this method these - * permissions will all be granted by - * {@link #grantReviewerPolicies(org.dspace.core.Context, org.dspace.workflowbasic.BasicWorkflowItem, - * org.dspace.eperson.EPerson)}. - * In most cases this method must be called within a try-finally-block that - * temporary disables the authentication system. This is not done by this - * method as it should be done carefully and only in contexts in which - * revoking the permissions is authorized by some previous checks. - * - * @param context - * @param item - * @throws SQLException - * @throws AuthorizeException - */ - protected void revokeReviewerPolicies(Context context, Item item) throws SQLException, AuthorizeException { - // get bundle "ORIGINAL" - Bundle originalBundle; - try { - originalBundle = itemService.getBundles(item, "ORIGINAL").get(0); - } catch (IndexOutOfBoundsException ex) { - originalBundle = null; - } - - // remove bitstream and bundle level policies - if (originalBundle != null) { - // We added policies for Bitstreams of the bundle "original" only - for (Bitstream bitstream : originalBundle.getBitstreams()) { - authorizeService.removeAllPoliciesByDSOAndType(context, bitstream, ResourcePolicy.TYPE_WORKFLOW); - } - - authorizeService.removeAllPoliciesByDSOAndType(context, originalBundle, ResourcePolicy.TYPE_WORKFLOW); - } - - // remove item level policies - authorizeService.removeAllPoliciesByDSOAndType(context, item, ResourcePolicy.TYPE_WORKFLOW); - } - - @Override - public BasicWorkflowItem start(Context context, WorkspaceItem wsi) - throws SQLException, AuthorizeException, IOException { - Item myitem = wsi.getItem(); - Collection collection = wsi.getCollection(); - - log.info(LogManager.getHeader(context, "start_workflow", "workspace_item_id=" - + wsi.getID() + "item_id=" + myitem.getID() + "collection_id=" - + collection.getID())); - - // record the start of the workflow w/provenance message - recordStart(context, myitem); - - // create the WorkflowItem - BasicWorkflowItem wfi = workflowItemService.create(context, myitem, collection); - wfi.setMultipleFiles(wsi.hasMultipleFiles()); - wfi.setMultipleTitles(wsi.hasMultipleTitles()); - wfi.setPublishedBefore(wsi.isPublishedBefore()); - - // remove the WorkspaceItem - workspaceItemService.deleteWrapper(context, wsi); - - // now get the workflow started - wfi.setState(WFSTATE_SUBMIT); - advance(context, wfi, null); - - // Return the workflow item - return wfi; - } - - @Override - public BasicWorkflowItem startWithoutNotify(Context c, WorkspaceItem wsi) - throws SQLException, AuthorizeException, IOException { - // make a hash table entry with item ID for no notify - // notify code checks no notify hash for item id - noEMail.put(wsi.getItem().getID(), Boolean.TRUE); - - return start(c, wsi); - } - - @Override - public List getOwnedTasks(Context context, EPerson e) - throws java.sql.SQLException { - return workflowItemService.findByOwner(context, e); - } - - - @Override - public List getPooledTasks(Context context, EPerson e) throws SQLException { - return workflowItemService.findPooledTasks(context, e); - } - - - @Override - public void claim(Context context, BasicWorkflowItem workflowItem, EPerson e) - throws SQLException, IOException, AuthorizeException { - int taskstate = workflowItem.getState(); - - switch (taskstate) { - case WFSTATE_STEP1POOL: - - authorizeService - .authorizeAction(context, e, workflowItem.getCollection(), Constants.WORKFLOW_STEP_1, true); - doState(context, workflowItem, WFSTATE_STEP1, e); - - break; - - case WFSTATE_STEP2POOL: - - authorizeService - .authorizeAction(context, e, workflowItem.getCollection(), Constants.WORKFLOW_STEP_2, true); - doState(context, workflowItem, WFSTATE_STEP2, e); - - break; - - case WFSTATE_STEP3POOL: - - authorizeService - .authorizeAction(context, e, workflowItem.getCollection(), Constants.WORKFLOW_STEP_3, true); - doState(context, workflowItem, WFSTATE_STEP3, e); - - break; - - default: - throw new IllegalArgumentException("Workflow Step " + taskstate + " is out of range."); - } - - log.info(LogManager.getHeader(context, "claim_task", "workflow_item_id=" - + workflowItem.getID() + "item_id=" + workflowItem.getItem().getID() - + "collection_id=" + workflowItem.getCollection().getID() - + "newowner_id=" + workflowItem.getOwner().getID() + "old_state=" - + taskstate + "new_state=" + workflowItem.getState())); - } - - @Override - public void advance(Context context, BasicWorkflowItem workflowItem, EPerson e) - throws SQLException, IOException, AuthorizeException { - advance(context, workflowItem, e, true, true); - } - - @Override - public boolean advance(Context context, BasicWorkflowItem workflowItem, EPerson e, - boolean curate, boolean record) - throws SQLException, IOException, AuthorizeException { - int taskstate = workflowItem.getState(); - boolean archived = false; - - // perform curation tasks if needed - if (curate && workflowCuratorService.needsCuration(workflowItem)) { - if (!workflowCuratorService.doCuration(context, workflowItem)) { - // don't proceed - either curation tasks queued, or item rejected - log.info(LogManager.getHeader(context, "advance_workflow", - "workflow_item_id=" + workflowItem.getID() + ",item_id=" - + workflowItem.getItem().getID() + ",collection_id=" - + workflowItem.getCollection().getID() + ",old_state=" - + taskstate + ",doCuration=false")); - return false; - } - } - - switch (taskstate) { - case WFSTATE_SUBMIT: - archived = doState(context, workflowItem, WFSTATE_STEP1POOL, e); - break; - - case WFSTATE_STEP1: - // advance(...) will call itself if no workflow step group exists - // so we need to check permissions only if a workflow step group is - // in place. - if (workflowItem.getCollection().getWorkflowStep1(context) != null && e != null) { - authorizeService - .authorizeAction(context, e, workflowItem.getCollection(), Constants.WORKFLOW_STEP_1, true); - } - - // Record provenance - if (record) { - recordApproval(context, workflowItem, e); - } - archived = doState(context, workflowItem, WFSTATE_STEP2POOL, e); - break; - - case WFSTATE_STEP2: - // advance(...) will call itself if no workflow step group exists - // so we need to check permissions only if a workflow step group is - // in place. - if (workflowItem.getCollection().getWorkflowStep2(context) != null && e != null) { - authorizeService - .authorizeAction(context, e, workflowItem.getCollection(), Constants.WORKFLOW_STEP_2, true); - } - - // Record provenance - if (record) { - recordApproval(context, workflowItem, e); - } - archived = doState(context, workflowItem, WFSTATE_STEP3POOL, e); - break; - - case WFSTATE_STEP3: - // advance(...) will call itself if no workflow step group exists - // so we need to check permissions only if a workflow step group is - // in place. - if (workflowItem.getCollection().getWorkflowStep3(context) != null && e != null) { - authorizeService - .authorizeAction(context, e, workflowItem.getCollection(), Constants.WORKFLOW_STEP_3, true); - } - - // We don't record approval for editors, since they can't reject, - // and thus didn't actually make a decision - archived = doState(context, workflowItem, WFSTATE_ARCHIVE, e); - break; - - default: - // error handling? shouldn't get here - break; - } - - log.info(LogManager.getHeader(context, "advance_workflow", - "workflow_item_id=" + workflowItem.getID() + ",item_id=" - + workflowItem.getItem().getID() + ",collection_id=" - + workflowItem.getCollection().getID() + ",old_state=" - + taskstate + ",new_state=" + workflowItem.getState())); - return archived; - } - - @Override - public void unclaim(Context context, BasicWorkflowItem workflowItem, EPerson e) - throws SQLException, IOException, AuthorizeException { - int taskstate = workflowItem.getState(); - - switch (taskstate) { - case WFSTATE_STEP1: - - doState(context, workflowItem, WFSTATE_STEP1POOL, e); - - break; - - case WFSTATE_STEP2: - - doState(context, workflowItem, WFSTATE_STEP2POOL, e); - - break; - - case WFSTATE_STEP3: - - doState(context, workflowItem, WFSTATE_STEP3POOL, e); - - break; - default: - throw new IllegalStateException("WorkflowItem reach an unknown state."); - } - - log.info(LogManager.getHeader(context, "unclaim_workflow", - "workflow_item_id=" + workflowItem.getID() + ",item_id=" - + workflowItem.getItem().getID() + ",collection_id=" - + workflowItem.getCollection().getID() + ",old_state=" - + taskstate + ",new_state=" + workflowItem.getState())); - } - - @Override - public WorkspaceItem abort(Context context, BasicWorkflowItem workflowItem, EPerson e) - throws SQLException, AuthorizeException, IOException { - // authorize a DSpaceActions.ABORT - if (!authorizeService.isAdmin(context)) { - throw new AuthorizeException( - "You must be an admin to abort a workflow"); - } - - // stop workflow regardless of its state - taskListItemService.deleteByWorkflowItem(context, workflowItem); - - log.info(LogManager.getHeader(context, "abort_workflow", "workflow_item_id=" - + workflowItem.getID() + "item_id=" + workflowItem.getItem().getID() - + "collection_id=" + workflowItem.getCollection().getID() + "eperson_id=" - + e.getID())); - - // convert into personal workspace - return returnToWorkspace(context, workflowItem); - } - - protected boolean doState(Context context, BasicWorkflowItem workflowItem, int newstate, - EPerson newowner) throws SQLException, IOException, - AuthorizeException { - Collection collection = workflowItem.getCollection(); - - //Gather our old data for launching the workflow event - int oldState = workflowItem.getState(); - - // in case we don't want to inform reviewers about tasks returned to - // the pool by other reviewers, we'll ne to know whether they were owned - // before. => keep this information before setting the new owner. - EPerson oldOwner = workflowItem.getOwner(); - - switch (newstate) { - case WFSTATE_STEP1POOL: - return pool(context, workflowItem, 1); - - case WFSTATE_STEP1: - assignToReviewer(context, workflowItem, 1, newowner); - return false; - - case WFSTATE_STEP2POOL: - return pool(context, workflowItem, 2); - - case WFSTATE_STEP2: - assignToReviewer(context, workflowItem, 2, newowner); - return false; - - case WFSTATE_STEP3POOL: - return pool(context, workflowItem, 3); - - case WFSTATE_STEP3: - assignToReviewer(context, workflowItem, 3, newowner); - return false; - - case WFSTATE_ARCHIVE: - // put in archive in one transaction - // remove workflow tasks - taskListItemService.deleteByWorkflowItem(context, workflowItem); - - collection = workflowItem.getCollection(); - - Item myitem = archive(context, workflowItem); - - // now email notification - notifyOfArchive(context, myitem, collection); - - // remove any workflow policies left - try { - context.turnOffAuthorisationSystem(); - revokeReviewerPolicies(context, myitem); - } finally { - context.restoreAuthSystemState(); - } - - logWorkflowEvent(context, workflowItem.getItem(), workflowItem, context.getCurrentUser(), newstate, - newowner, collection, oldState, null); - - return true; - - default: - throw new IllegalArgumentException("BasicWorkflowService cannot handle workflowItemState " + newstate); - - } - } - - /** - * Helper method to take an item out of the pool, to assign it to a reviewer and to deal with reviewer policies. - * Don't use this method directly. Instead: use {@link #start(Context, WorkspaceItem)} to start a workflow and - * {@link #claim(Context, BasicWorkflowItem, EPerson)} as those methods handles the internal states and checks for - * the appropriate permissions. - * - * @param context DSpace context object - * @param workflowItem The item that shall be pooled. - * @param step The step (1-3) of the pool the item should be put to. - * @param newowner The EPerson that should do the review. - * @return True if the item was archived because no reviewers were assigned to any of the following workflow - * steps, false otherwise. - * @throws SQLException - * @throws AuthorizeException - * @throws IOException - * @throws IllegalArgumentException If {@code param} has another value than either 1, 2, or 3. - */ - protected void assignToReviewer(Context context, BasicWorkflowItem workflowItem, int step, EPerson newowner) - throws AuthorizeException, SQLException { - // shortcut to the collection - Collection collection = workflowItem.getCollection(); - - // from the step we can recoginze the new state and the corresponding policy action. - int newState; - int correspondingAction; - if (step == 1) { - newState = WFSTATE_STEP1; - correspondingAction = Constants.WORKFLOW_STEP_1; - } else if (step == 2) { - newState = WFSTATE_STEP2; - correspondingAction = Constants.WORKFLOW_STEP_2; - } else if (step == 3) { - newState = WFSTATE_STEP3; - correspondingAction = Constants.WORKFLOW_STEP_3; - } else { - throw new IllegalArgumentException("Got a task to pool with an improperly or unknown state."); - } - - // Gather the old state for logging - int oldState = workflowItem.getState(); - - // if there is a workflow state group and it contains any members, - // then we have to check permissions first - if ((collectionService.getWorkflowGroup(context, collection, step) != null) - && !(groupService.isEmpty(collectionService.getWorkflowGroup(context, collection, step))) - && newowner != null) { - authorizeService.authorizeAction(context, newowner, collection, correspondingAction, true); - } - - // give the owner the appropriate permissions - try { - context.turnOffAuthorisationSystem(); - // maybe unnecessary, but revoke any previously granted permissions - revokeReviewerPolicies(context, workflowItem.getItem()); - // finally grant the new permissions - grantReviewerPolicies(context, workflowItem, newowner); - } finally { - context.restoreAuthSystemState(); - } - - // remove task from tasklist as someone is working on it now - taskListItemService.deleteByWorkflowItem(context, workflowItem); - // assign new owner - workflowItem.setState(newState); - workflowItem.setOwner(newowner); - - logWorkflowEvent(context, workflowItem.getItem(), workflowItem, context.getCurrentUser(), newState, newowner, - collection, oldState, null); - } - - /** - * Helper method that manages state, policies, owner, notifies, tasklistitems and so on whenever an WorkflowItem - * should be added to a workflow step pool. Don't use this method directly. Either use - * {@link #unclaim(Context, BasicWorkflowItem, EPerson)} if the item is claimed, - * {@link #start(Context, WorkspaceItem)} to start the workflow or - * {@link #advance(Context, BasicWorkflowItem, EPerson)} - * to move an item to the next state. - * - * @param context DSpace context object - * @param workflowItem The item that shall be pooled. - * @param step The step (1-3) of the pool the item should be put to. - * @return True if the item was archived because no reviewers were assigned to any of the following workflow - * steps, false otherwise. - * @throws SQLException - * @throws AuthorizeException - * @throws IOException - * @throws IllegalArgumentException If {@code param} has another value than either 1, 2, or 3. - */ - protected boolean pool(Context context, BasicWorkflowItem workflowItem, int step) - throws SQLException, AuthorizeException, IOException { - // shortcut to the collection - Collection collection = workflowItem.getCollection(); - - // from the step we can recoginze the new state and the corresponding state. - // the new state is the pool of the step - // the corresponding state is the state an item gets when it gets claimed. That is important to recognize if we - // have to send notifications and if we have to skip a pool. - int newState; - int correspondingState; - if (step == 1) { - newState = WFSTATE_STEP1POOL; - correspondingState = WFSTATE_STEP1; - } else if (step == 2) { - newState = WFSTATE_STEP2POOL; - correspondingState = WFSTATE_STEP2; - } else if (step == 3) { - newState = WFSTATE_STEP3POOL; - correspondingState = WFSTATE_STEP3; - } else { - throw new IllegalArgumentException("Got a task to pool with an improperly or unknown state."); - } - - // Gather our old owner and state as we need those as well to determine if we have to send notifies - int oldState = workflowItem.getState(); - EPerson oldOwner = workflowItem.getOwner(); - - // clear owner - workflowItem.setOwner(null); - // don't revoke the reviewer policies yet, they may be needed to advance the item - - // any approvers? - // if so, add them to tasklist - // if not, skip to next state - Group workflowStepGroup = collectionService.getWorkflowGroup(context, collection, step); - - if ((workflowStepGroup != null) && !(groupService.isEmpty(workflowStepGroup))) { - // set new item state - workflowItem.setState(newState); - - // revoke previously granted reviewer policies and grant read permissions - try { - context.turnOffAuthorisationSystem(); - // revoke previously granted policies - revokeReviewerPolicies(context, workflowItem.getItem()); - - // JSPUI offers a preview to every task before a reviewer claims it. - // So we need to grant permissions in advance, so that all possible reviewers can read the item and all - // bitstreams in the bundle "ORIGINAL". - authorizeService.addPolicy(context, workflowItem.getItem(), Constants.READ, workflowStepGroup, - ResourcePolicy.TYPE_WORKFLOW); - Bundle originalBundle; - try { - originalBundle = itemService.getBundles(workflowItem.getItem(), "ORIGINAL").get(0); - } catch (IndexOutOfBoundsException ex) { - originalBundle = null; - } - if (originalBundle != null) { - authorizeService.addPolicy(context, originalBundle, Constants.READ, workflowStepGroup, - ResourcePolicy.TYPE_WORKFLOW); - for (Bitstream bitstream : originalBundle.getBitstreams()) { - authorizeService.addPolicy(context, bitstream, Constants.READ, workflowStepGroup, - ResourcePolicy.TYPE_WORKFLOW); - } - } - } finally { - context.restoreAuthSystemState(); - } - - // get a list of all epeople in group (or any subgroups) - List epa = groupService.allMembers(context, workflowStepGroup); - - // there were reviewers, change the state - // and add them to the list - createTasks(context, workflowItem, epa); - - if (configurationService.getBooleanProperty("workflow.notify.returned.tasks", true) - || oldState != correspondingState - || oldOwner == null) { - // email notification - notifyGroupOfTask(context, workflowItem, workflowStepGroup, epa); - } - logWorkflowEvent(context, workflowItem.getItem(), workflowItem, context.getCurrentUser(), newState, null, - collection, oldState, workflowStepGroup); - return false; - } else { - // no reviewers, skip ahead - workflowItem.setState(correspondingState); - boolean archived = advance(context, workflowItem, null, true, false); - if (archived) { - // remove any workflow policies that may have left over - try { - context.turnOffAuthorisationSystem(); - revokeReviewerPolicies(context, workflowItem.getItem()); - } finally { - context.restoreAuthSystemState(); - } - } - return archived; - } - } - - protected void logWorkflowEvent(Context context, Item item, BasicWorkflowItem workflowItem, EPerson actor, - int newstate, EPerson newOwner, Collection mycollection, int oldState, - Group newOwnerGroup) { - if (newstate == WFSTATE_ARCHIVE || newstate == WFSTATE_STEP1POOL || newstate == WFSTATE_STEP2POOL || newstate - == WFSTATE_STEP3POOL) { - //Clear the newowner variable since this one isn't owned anymore ! - newOwner = null; - } - - UsageWorkflowEvent usageWorkflowEvent = new UsageWorkflowEvent(context, item, workflowItem, - workflowText[newstate], workflowText[oldState], - mycollection, actor); - if (newOwner != null) { - usageWorkflowEvent.setEpersonOwners(newOwner); - } - if (newOwnerGroup != null) { - usageWorkflowEvent.setGroupOwners(newOwnerGroup); - } - DSpaceServicesFactory.getInstance().getEventService().fireEvent(usageWorkflowEvent); - } - - @Override - public String getWorkflowText(int state) { - if (state > -1 && state < workflowText.length) { - return workflowText[state]; - } - - throw new IllegalArgumentException("Invalid workflow state passed"); - } - - /** - * Commit the contained item to the main archive. The item is associated - * with the relevant collection, added to the search index, and any other - * tasks such as assigning dates are performed. - * - * @param context The relevant DSpace Context. - * @param workflowItem which workflow item to archive - * @return the fully archived item. - * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. - * @throws SQLException An exception that provides information on a database access error or other errors. - * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. - */ - protected Item archive(Context context, BasicWorkflowItem workflowItem) - throws SQLException, IOException, AuthorizeException { - Item item = workflowItem.getItem(); - Collection collection = workflowItem.getCollection(); - - log.info(LogManager.getHeader(context, "archive_item", "workflow_item_id=" - + workflowItem.getID() + "item_id=" + item.getID() + "collection_id=" - + collection.getID())); - - installItemService.installItem(context, workflowItem); - - // Log the event - log.info(LogManager.getHeader(context, "install_item", "workflow_id=" - + workflowItem.getID() + ", item_id=" + item.getID() + "handle=FIXME")); - - return item; - } - - /** - * notify the submitter that the item is archived - * - * @param context The relevant DSpace Context. - * @param item which item was archived - * @param coll collection name to display in template - * @throws SQLException An exception that provides information on a database access error or other errors. - * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. - */ - protected void notifyOfArchive(Context context, Item item, Collection coll) - throws SQLException, IOException { - try { - // Get submitter - EPerson ep = item.getSubmitter(); - - // send the notification to the submitter unless the submitter eperson has been deleted - if (ep != null) { - // Get the Locale - Locale supportedLocale = I18nUtil.getEPersonLocale(ep); - Email email = Email.getEmail(I18nUtil.getEmailFilename(supportedLocale, "submit_archive")); - - // Get the item handle to email to user - String handle = handleService.findHandle(context, item); - - // Get title - String title = item.getName(); - if (StringUtils.isBlank(title)) { - try { - title = I18nUtil.getMessage("org.dspace.workflow.WorkflowManager.untitled"); - } catch (MissingResourceException e) { - title = "Untitled"; - } - } - - email.addRecipient(ep.getEmail()); - email.addArgument(title); - email.addArgument(coll.getName()); - email.addArgument(handleService.getCanonicalForm(handle)); - - email.send(); - } - } catch (MessagingException e) { - log.warn(LogManager.getHeader(context, "notifyOfArchive", - "cannot email user; item_id=" + item.getID() - + ": " + e.getMessage())); - } - } - - /** - * Return the workflow item to the workspace of the submitter. The workflow - * item is removed, and a workspace item created. - * - * @param c Context - * @param wfi WorkflowItem to be 'dismantled' - * @return the workspace item - * @throws SQLException An exception that provides information on a database access error or other errors. - * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. - * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. - */ - protected WorkspaceItem returnToWorkspace(Context c, BasicWorkflowItem wfi) - throws SQLException, IOException, AuthorizeException { - // Regarding auth: this method is protected. - // Authorization should be checked in all public methods calling this one. - // FIXME: How should this interact with the workflow system? - // FIXME: Remove license - // FIXME: Provenance statement? - // Create the new workspace item row - WorkspaceItem workspaceItem = workspaceItemService.create(c, wfi); - - workspaceItem.setMultipleFiles(wfi.hasMultipleFiles()); - workspaceItem.setMultipleTitles(wfi.hasMultipleTitles()); - workspaceItem.setPublishedBefore(wfi.isPublishedBefore()); - workspaceItemService.update(c, workspaceItem); - - //myitem.update(); - log.info(LogManager.getHeader(c, "return_to_workspace", - "workflow_item_id=" + wfi.getID() + "workspace_item_id=" - + workspaceItem.getID())); - - // Now remove the workflow object manually from the database - workflowItemService.deleteWrapper(c, wfi); - - return workspaceItem; - } - - @Override - public void deleteWorkflowByWorkflowItem(Context context, BasicWorkflowItem wi, EPerson e) - throws SQLException, AuthorizeException, IOException { - Item myitem = wi.getItem(); - UUID itemID = myitem.getID(); - Integer workflowID = wi.getID(); - UUID collID = wi.getCollection().getID(); - // stop workflow - taskListItemService.deleteByWorkflowItem(context, wi); - // Now remove the workflow object manually from the database - workflowItemService.deleteWrapper(context, wi); - // Now delete the item - itemService.delete(context, myitem); - log.info(LogManager.getHeader(context, "delete_workflow", String.format("workflow_item_id=%s " + - "item_id=%s collection_id=%s eperson_id=%s", workflowID, itemID, collID, e.getID()))); - } - - @Override - public WorkspaceItem sendWorkflowItemBackSubmission(Context context, BasicWorkflowItem workflowItem, - EPerson ePerson, - String provenancePrefix, String rejection_message) - throws SQLException, AuthorizeException, - IOException { - int oldState = workflowItem.getState(); - - switch (oldState) { - case WFSTATE_STEP1: - authorizeService - .authorizeActionBoolean(context, ePerson, workflowItem.getItem(), Constants.WORKFLOW_STEP_1, true); - break; - case WFSTATE_STEP2: - authorizeService - .authorizeActionBoolean(context, ePerson, workflowItem.getItem(), Constants.WORKFLOW_STEP_2, true); - break; - case WFSTATE_STEP3: - authorizeService - .authorizeActionBoolean(context, ePerson, workflowItem.getItem(), Constants.WORKFLOW_STEP_3, true); - break; - default: - throw new IllegalArgumentException("Workflow Step " + oldState + " is out of range."); - } - - - // stop workflow - taskListItemService.deleteByWorkflowItem(context, workflowItem); - - // rejection provenance - Item myitem = workflowItem.getItem(); - - // Get current date - String now = DCDate.getCurrent().toString(); - - // Get user's name + email address - String usersName = getEPersonName(ePerson); - - // Here's what happened - String provDescription = "Rejected by " + usersName + ", reason: " - + rejection_message + " on " + now + " (GMT) "; - - // Add to item as a DC field - itemService.addMetadata(context, myitem, MetadataSchemaEnum.DC.getName(), - "description", "provenance", "en", provDescription); - itemService.update(context, myitem); - - // convert into personal workspace - WorkspaceItem wsi = returnToWorkspace(context, workflowItem); - - // notify that it's been rejected - notifyOfReject(context, workflowItem, ePerson, rejection_message); - - log.info(LogManager.getHeader(context, "reject_workflow", "workflow_item_id=" - + workflowItem.getID() + "item_id=" + workflowItem.getItem().getID() - + "collection_id=" + workflowItem.getCollection().getID() + "eperson_id=" - + ePerson.getID())); - - logWorkflowEvent(context, wsi.getItem(), workflowItem, ePerson, WFSTATE_SUBMIT, null, wsi.getCollection(), - oldState, null); - - return wsi; - } - - // creates workflow tasklist entries for a workflow - // for all the given EPeople - protected void createTasks(Context c, BasicWorkflowItem wi, List epa) - throws SQLException { - // create a tasklist entry for each eperson - for (EPerson anEpa : epa) { - // can we get away without creating a tasklistitem class? - // do we want to? - taskListItemService.create(c, wi, anEpa); - } - } - - // send notices of curation activity - @Override - public void notifyOfCuration(Context c, BasicWorkflowItem wi, List ePeople, - String taskName, String action, String message) throws SQLException, IOException { - try { - // Get the item title - String title = getItemTitle(wi); - - // Get the submitter's name - String submitter = getSubmitterName(wi); - - // Get the collection - Collection coll = wi.getCollection(); - - for (EPerson epa : ePeople) { - Locale supportedLocale = I18nUtil.getEPersonLocale(epa); - Email email = Email.getEmail(I18nUtil.getEmailFilename(supportedLocale, - "flowtask_notify")); - email.addArgument(title); - email.addArgument(coll.getName()); - email.addArgument(submitter); - email.addArgument(taskName); - email.addArgument(message); - email.addArgument(action); - email.addRecipient(epa.getEmail()); - email.send(); - } - } catch (MessagingException e) { - log.warn(LogManager.getHeader(c, "notifyOfCuration", - "cannot email users of workflow_item_id " + wi.getID() - + ": " + e.getMessage())); - } - } - - protected void notifyGroupOfTask(Context c, BasicWorkflowItem wi, - Group mygroup, List epa) throws SQLException, IOException { - // check to see if notification is turned off - // and only do it once - delete key after notification has - // been suppressed for the first time - UUID myID = wi.getItem().getID(); - - if (noEMail.containsKey(myID)) { - // suppress email, and delete key - noEMail.remove(myID); - } else { - try { - // Get the item title - String title = getItemTitle(wi); - - // Get the submitter's name - String submitter = getSubmitterName(wi); - - // Get the collection - Collection coll = wi.getCollection(); - - String message = ""; - - for (EPerson anEpa : epa) { - Locale supportedLocale = I18nUtil.getEPersonLocale(anEpa); - Email email = Email.getEmail(I18nUtil.getEmailFilename(supportedLocale, "submit_task")); - email.addArgument(title); - email.addArgument(coll.getName()); - email.addArgument(submitter); - - ResourceBundle messages = ResourceBundle.getBundle("Messages", supportedLocale); - switch (wi.getState()) { - case WFSTATE_STEP1POOL: - message = messages.getString("org.dspace.workflow.WorkflowManager.step1"); - break; - - case WFSTATE_STEP2POOL: - message = messages.getString("org.dspace.workflow.WorkflowManager.step2"); - break; - - case WFSTATE_STEP3POOL: - message = messages.getString("org.dspace.workflow.WorkflowManager.step3"); - break; - default: - break; - } - email.addArgument(message); - email.addArgument(getMyDSpaceLink()); - email.addRecipient(anEpa.getEmail()); - email.send(); - } - } catch (MessagingException e) { - String gid = (mygroup != null) ? - String.valueOf(mygroup.getID()) : "none"; - log.warn(LogManager.getHeader(c, "notifyGroupofTask", - "cannot email user group_id=" + gid - + " workflow_item_id=" + wi.getID() - + ": " + e.getMessage())); - } - } - } - - @Override - public String getMyDSpaceLink() { - return configurationService.getProperty("dspace.ui.url") + "/mydspace"; - } - - protected void notifyOfReject(Context context, BasicWorkflowItem workflowItem, EPerson e, - String reason) { - try { - // Get submitter - EPerson ep = workflowItem.getSubmitter(); - // send the notification only if the person was not deleted in the meantime - if (ep != null) { - // Get the item title - String title = getItemTitle(workflowItem); - - // Get the collection - Collection coll = workflowItem.getCollection(); - - // Get rejector's name - String rejector = getEPersonName(e); - Locale supportedLocale = I18nUtil.getEPersonLocale(e); - Email email = Email.getEmail(I18nUtil.getEmailFilename(supportedLocale, "submit_reject")); - - email.addRecipient(ep.getEmail()); - email.addArgument(title); - email.addArgument(coll.getName()); - email.addArgument(rejector); - email.addArgument(reason); - email.addArgument(getMyDSpaceLink()); - - email.send(); - } - } catch (RuntimeException re) { - // log this email error - log.warn(LogManager.getHeader(context, "notify_of_reject", - "cannot email user eperson_id=" + e.getID() - + " eperson_email=" + e.getEmail() - + " workflow_item_id=" + workflowItem.getID() - + ": " + re.getMessage())); - - throw re; - } catch (Exception ex) { - // log this email error - log.warn(LogManager.getHeader(context, "notify_of_reject", - "cannot email user eperson_id=" + e.getID() - + " eperson_email=" + e.getEmail() - + " workflow_item_id=" + workflowItem.getID() - + ": " + ex.getMessage())); - } - } - - @Override - public String getItemTitle(BasicWorkflowItem wi) throws SQLException { - Item myitem = wi.getItem(); - String title = myitem.getName(); - - // only return the first element, or "Untitled" - if (StringUtils.isNotBlank(title)) { - return title; - } else { - return I18nUtil.getMessage("org.dspace.workflow.WorkflowManager.untitled "); - } - } - - @Override - public String getSubmitterName(BasicWorkflowItem wi) throws SQLException { - EPerson e = wi.getSubmitter(); - if (e == null) { - return null; - } - return getEPersonName(e); - } - - protected String getEPersonName(EPerson e) throws SQLException { - if (e == null) { - return "Unknown"; - } - String submitter = e.getFullName(); - - submitter = submitter + " (" + e.getEmail() + ")"; - - return submitter; - } - - // Record approval provenance statement - protected void recordApproval(Context context, BasicWorkflowItem workflowItem, EPerson e) - throws SQLException, IOException, AuthorizeException { - Item item = workflowItem.getItem(); - - // Get user's name + email address - String usersName = getEPersonName(e); - - // Get current date - String now = DCDate.getCurrent().toString(); - - // Here's what happened - String provDescription = "Approved for entry into archive by " - + usersName + " on " + now + " (GMT) "; - - // add bitstream descriptions (name, size, checksums) - provDescription += installItemService.getBitstreamProvenanceMessage(context, item); - - // Add to item as a DC field - itemService.addMetadata(context, item, MetadataSchemaEnum.DC.getName(), - "description", "provenance", "en", provDescription); - itemService.update(context, item); - } - - // Create workflow start provenance message - protected void recordStart(Context context, Item myitem) - throws SQLException, IOException, AuthorizeException { - // get date - DCDate now = DCDate.getCurrent(); - - // Create provenance description - String provmessage; - - if (myitem.getSubmitter() != null) { - provmessage = "Submitted by " + myitem.getSubmitter().getFullName() - + " (" + myitem.getSubmitter().getEmail() + ") on " - + now.toString() + "\n"; - } else { - // else, null submitter - provmessage = "Submitted by unknown (probably automated) on" - + now.toString() + "\n"; - } - - // add sizes and checksums of bitstreams - provmessage += installItemService.getBitstreamProvenanceMessage(context, myitem); - - // Add message to the DC - itemService.addMetadata(context, myitem, MetadataSchemaEnum.DC.getName(), - "description", "provenance", "en", provmessage); - itemService.update(context, myitem); - } - - @Override - public void deleteCollection(Context context, Collection collection) - throws SQLException, IOException, AuthorizeException { - authorizeService.authorizeAction(context, collection, Constants.WRITE); - collection.setWorkflowGroup(context, 1, null); - collection.setWorkflowGroup(context, 2, null); - collection.setWorkflowGroup(context, 3, null); - workflowItemService.deleteByCollection(context, collection); - } - - @Override - public List getEPersonDeleteConstraints(Context context, EPerson ePerson) throws SQLException { - List resultList = new ArrayList<>(); - List workflowItems = workflowItemService.findByOwner(context, ePerson); - if (CollectionUtils.isNotEmpty(workflowItems)) { - resultList.add("workflowitem"); - } - List taskListItems = taskListItemService.findByEPerson(context, ePerson); - if (CollectionUtils.isNotEmpty(taskListItems)) { - resultList.add("tasklistitem"); - } - return resultList; - } - - @Override - public Group getWorkflowRoleGroup(Context context, Collection collection, String roleName, Group roleGroup) - throws SQLException, AuthorizeException { - if ("WF_STEP1".equals(roleName)) { - roleGroup = collection.getWorkflowStep1(context); - if (roleGroup == null) { - roleGroup = collectionService.createWorkflowGroup(context, collection, 1); - } - - } else if ("WF_STEP2".equals(roleName)) { - roleGroup = collection.getWorkflowStep2(context); - if (roleGroup == null) { - roleGroup = collectionService.createWorkflowGroup(context, collection, 2); - } - } else if ("WF_STEP3".equals(roleName)) { - roleGroup = collection.getWorkflowStep3(context); - if (roleGroup == null) { - roleGroup = collectionService.createWorkflowGroup(context, collection, 3); - } - - } - return roleGroup; - } - - @Override - public Group createWorkflowRoleGroup(Context context, Collection collection, String roleName) - throws AuthorizeException, SQLException { - return getWorkflowRoleGroup(context, collection, roleName, null); - } - - @Override - public List getFlywayMigrationLocations() { - return Collections.emptyList(); - } // TODO -} diff --git a/dspace-api/src/main/java/org/dspace/workflowbasic/TaskListItem.java b/dspace-api/src/main/java/org/dspace/workflowbasic/TaskListItem.java deleted file mode 100644 index 82a9438f68..0000000000 --- a/dspace-api/src/main/java/org/dspace/workflowbasic/TaskListItem.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.workflowbasic; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.SequenceGenerator; -import javax.persistence.Table; - -import org.dspace.core.Context; -import org.dspace.core.ReloadableEntity; -import org.dspace.eperson.EPerson; - -/** - * Database entity representation of the TaskListItem table - * - * @author kevinvandevelde at atmire.com - */ -@Entity -@Table(name = "tasklistitem") -public class TaskListItem implements ReloadableEntity { - - @Id - @Column(name = "tasklist_id", unique = true, nullable = false) - @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tasklistitem_seq") - @SequenceGenerator(name = "tasklistitem_seq", sequenceName = "tasklistitem_seq", allocationSize = 1) - private int taskListItemId; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "eperson_id") - private EPerson ePerson; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "workflow_id") - private BasicWorkflowItem workflowItem; - - /** - * Protected constructor, create object using: - * {@link org.dspace.workflowbasic.service.TaskListItemService#create(Context, BasicWorkflowItem, EPerson)} - */ - protected TaskListItem() { - - } - - public int getTaskListItemId() { - return taskListItemId; - } - - public EPerson getEPerson() { - return ePerson; - } - - public BasicWorkflowItem getWorkflowItem() { - return workflowItem; - } - - void setEPerson(EPerson ePerson) { - this.ePerson = ePerson; - } - - void setWorkflowItem(BasicWorkflowItem workflowItem) { - this.workflowItem = workflowItem; - } - - public Integer getID() { - return taskListItemId; - } -} diff --git a/dspace-api/src/main/java/org/dspace/workflowbasic/TaskListItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/workflowbasic/TaskListItemServiceImpl.java deleted file mode 100644 index ba55ca9460..0000000000 --- a/dspace-api/src/main/java/org/dspace/workflowbasic/TaskListItemServiceImpl.java +++ /dev/null @@ -1,69 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.workflowbasic; - -import java.sql.SQLException; -import java.util.List; - -import org.dspace.core.Context; -import org.dspace.eperson.EPerson; -import org.dspace.workflowbasic.dao.TaskListItemDAO; -import org.dspace.workflowbasic.service.TaskListItemService; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * Service implementation for the TaskListItem object. - * This class is responsible for all business logic calls for the TaskListItem object and is autowired by spring. - * This class should never be accessed directly. - * - * @author kevinvandevelde at atmire.com - */ -public class TaskListItemServiceImpl implements TaskListItemService { - - @Autowired(required = true) - protected TaskListItemDAO taskListItemDAO; - - protected TaskListItemServiceImpl() { - - } - - @Override - public TaskListItem create(Context context, BasicWorkflowItem workflowItem, EPerson ePerson) throws SQLException { - TaskListItem taskListItem = taskListItemDAO.create(context, new TaskListItem()); - taskListItem.setWorkflowItem(workflowItem); - taskListItem.setEPerson(ePerson); - update(context, taskListItem); - return taskListItem; - } - - @Override - public void deleteByWorkflowItem(Context context, BasicWorkflowItem workflowItem) throws SQLException { - taskListItemDAO.deleteByWorkflowItem(context, workflowItem); - } - - @Override - public void deleteByWorkflowItemAndEPerson(Context context, BasicWorkflowItem workflowItem, EPerson ePerson) - throws SQLException { - taskListItemDAO.deleteByWorkflowItemAndEPerson(context, workflowItem, ePerson); - } - - @Override - public void deleteByEPerson(Context context, EPerson ePerson) throws SQLException { - taskListItemDAO.deleteByEPerson(context, ePerson); - } - - @Override - public void update(Context context, TaskListItem taskListItem) throws SQLException { - taskListItemDAO.save(context, taskListItem); - } - - @Override - public List findByEPerson(Context context, EPerson ePerson) throws SQLException { - return taskListItemDAO.findByEPerson(context, ePerson); - } -} diff --git a/dspace-api/src/main/java/org/dspace/workflowbasic/dao/BasicWorkflowItemDAO.java b/dspace-api/src/main/java/org/dspace/workflowbasic/dao/BasicWorkflowItemDAO.java deleted file mode 100644 index b8540d98fb..0000000000 --- a/dspace-api/src/main/java/org/dspace/workflowbasic/dao/BasicWorkflowItemDAO.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.workflowbasic.dao; - -import java.sql.SQLException; -import java.util.List; - -import org.dspace.content.Collection; -import org.dspace.content.Item; -import org.dspace.core.Context; -import org.dspace.core.GenericDAO; -import org.dspace.eperson.EPerson; -import org.dspace.workflowbasic.BasicWorkflowItem; - -/** - * Database Access Object interface class for the BasicWorkflowItem object. - * The implementation of this class is responsible for all database calls for the BasicWorkflowItem object and is - * autowired by spring - * This class should only be accessed from a single service and should never be exposed outside of the API - * - * @author kevinvandevelde at atmire.com - */ -public interface BasicWorkflowItemDAO extends GenericDAO { - - public BasicWorkflowItem findByItem(Context context, Item i) throws SQLException; - - public List findBySubmitter(Context context, EPerson ep) throws SQLException; - - public List findByCollection(Context context, Collection c) throws SQLException; - - public List findByPooledTasks(Context context, EPerson ePerson) throws SQLException; - - public List findByOwner(Context context, EPerson ePerson) throws SQLException; - - int countRows(Context context) throws SQLException; -} diff --git a/dspace-api/src/main/java/org/dspace/workflowbasic/dao/TaskListItemDAO.java b/dspace-api/src/main/java/org/dspace/workflowbasic/dao/TaskListItemDAO.java deleted file mode 100644 index 5cdf3e0611..0000000000 --- a/dspace-api/src/main/java/org/dspace/workflowbasic/dao/TaskListItemDAO.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.workflowbasic.dao; - -import java.sql.SQLException; -import java.util.List; - -import org.dspace.core.Context; -import org.dspace.core.GenericDAO; -import org.dspace.eperson.EPerson; -import org.dspace.workflowbasic.BasicWorkflowItem; -import org.dspace.workflowbasic.TaskListItem; - -/** - * Database Access Object interface class for the TaskListItem object. - * The implementation of this class is responsible for all database calls for the TaskListItem object and is - * autowired by spring - * This class should only be accessed from a single service and should never be exposed outside of the API - * - * @author kevinvandevelde at atmire.com - */ -public interface TaskListItemDAO extends GenericDAO { - - public void deleteByWorkflowItem(Context context, BasicWorkflowItem workflowItem) throws SQLException; - - public void deleteByWorkflowItemAndEPerson(Context context, BasicWorkflowItem workflowItem, EPerson ePerson) - throws SQLException; - - public void deleteByEPerson(Context context, EPerson ePerson) throws SQLException; - - public List findByEPerson(Context context, EPerson ePerson) throws SQLException; -} diff --git a/dspace-api/src/main/java/org/dspace/workflowbasic/dao/impl/BasicWorkflowItemDAOImpl.java b/dspace-api/src/main/java/org/dspace/workflowbasic/dao/impl/BasicWorkflowItemDAOImpl.java deleted file mode 100644 index d3ae4ba884..0000000000 --- a/dspace-api/src/main/java/org/dspace/workflowbasic/dao/impl/BasicWorkflowItemDAOImpl.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.workflowbasic.dao.impl; - -import java.sql.SQLException; -import java.util.LinkedList; -import java.util.List; -import javax.persistence.Query; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Join; -import javax.persistence.criteria.Root; - -import org.dspace.content.Collection; -import org.dspace.content.Item; -import org.dspace.content.Item_; -import org.dspace.core.AbstractHibernateDAO; -import org.dspace.core.Context; -import org.dspace.eperson.EPerson; -import org.dspace.workflowbasic.BasicWorkflowItem; -import org.dspace.workflowbasic.BasicWorkflowItem_; -import org.dspace.workflowbasic.dao.BasicWorkflowItemDAO; - -/** - * Hibernate implementation of the Database Access Object interface class for the BasicWorkflowItem object. - * This class is responsible for all database calls for the BasicWorkflowItem object and is autowired by spring - * This class should never be accessed directly. - * - * @author kevinvandevelde at atmire.com - */ -public class BasicWorkflowItemDAOImpl extends AbstractHibernateDAO implements BasicWorkflowItemDAO { - protected BasicWorkflowItemDAOImpl() { - super(); - } - - - @Override - public BasicWorkflowItem findByItem(Context context, Item i) throws SQLException { - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, BasicWorkflowItem.class); - Root basicWorkflowItemRoot = criteriaQuery.from(BasicWorkflowItem.class); - criteriaQuery.select(basicWorkflowItemRoot); - criteriaQuery.where(criteriaBuilder.equal(basicWorkflowItemRoot.get(BasicWorkflowItem_.item), i)); - return uniqueResult(context, criteriaQuery, false, BasicWorkflowItem.class, -1, -1); - } - - @Override - public List findBySubmitter(Context context, EPerson ep) throws SQLException { - - - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, BasicWorkflowItem.class); - Root basicWorkflowItemRoot = criteriaQuery.from(BasicWorkflowItem.class); - Join join = basicWorkflowItemRoot.join("item"); - criteriaQuery.select(basicWorkflowItemRoot); - criteriaQuery.where(criteriaBuilder.equal(join.get(Item_.submitter), ep)); - - List orderList = new LinkedList<>(); - orderList.add(criteriaBuilder.asc(basicWorkflowItemRoot.get(BasicWorkflowItem_.workflowitemId))); - criteriaQuery.orderBy(orderList); - - - return list(context, criteriaQuery, false, BasicWorkflowItem.class, -1, -1); - - } - - @Override - public List findByCollection(Context context, Collection c) throws SQLException { - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, BasicWorkflowItem.class); - Root basicWorkflowItemRoot = criteriaQuery.from(BasicWorkflowItem.class); - criteriaQuery.select(basicWorkflowItemRoot); - criteriaQuery.where(criteriaBuilder.equal(basicWorkflowItemRoot.get(BasicWorkflowItem_.collection), c)); - return list(context, criteriaQuery, false, BasicWorkflowItem.class, -1, -1); - } - - @Override - public List findByPooledTasks(Context context, EPerson ePerson) throws SQLException { - String queryString = "select wf from TaskListItem as tli join tli.workflowItem wf where tli.ePerson = " + - ":eperson ORDER BY wf.workflowitemId"; - Query query = createQuery(context, queryString); - query.setParameter("eperson", ePerson); - return list(query); - } - - @Override - public List findByOwner(Context context, EPerson ePerson) throws SQLException { - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, BasicWorkflowItem.class); - Root basicWorkflowItemRoot = criteriaQuery.from(BasicWorkflowItem.class); - criteriaQuery.select(basicWorkflowItemRoot); - criteriaQuery.where(criteriaBuilder.equal(basicWorkflowItemRoot.get(BasicWorkflowItem_.owner), ePerson)); - return list(context, criteriaQuery, false, BasicWorkflowItem.class, -1, -1); - } - - @Override - public int countRows(Context context) throws SQLException { - return count(createQuery(context, "SELECT count(*) FROM BasicWorkflowItem")); - } -} diff --git a/dspace-api/src/main/java/org/dspace/workflowbasic/dao/impl/TaskListItemDAOImpl.java b/dspace-api/src/main/java/org/dspace/workflowbasic/dao/impl/TaskListItemDAOImpl.java deleted file mode 100644 index 2f6448fb4e..0000000000 --- a/dspace-api/src/main/java/org/dspace/workflowbasic/dao/impl/TaskListItemDAOImpl.java +++ /dev/null @@ -1,72 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.workflowbasic.dao.impl; - -import java.sql.SQLException; -import java.util.List; -import javax.persistence.Query; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Root; - -import org.dspace.core.AbstractHibernateDAO; -import org.dspace.core.Context; -import org.dspace.eperson.EPerson; -import org.dspace.workflowbasic.BasicWorkflowItem; -import org.dspace.workflowbasic.TaskListItem; -import org.dspace.workflowbasic.TaskListItem_; -import org.dspace.workflowbasic.dao.TaskListItemDAO; - -/** - * Hibernate implementation of the Database Access Object interface class for the TaskListItem object. - * This class is responsible for all database calls for the TaskListItem object and is autowired by spring - * This class should never be accessed directly. - * - * @author kevinvandevelde at atmire.com - */ -public class TaskListItemDAOImpl extends AbstractHibernateDAO implements TaskListItemDAO { - protected TaskListItemDAOImpl() { - super(); - } - - @Override - public void deleteByWorkflowItem(Context context, BasicWorkflowItem workflowItem) throws SQLException { - String queryString = "delete from TaskListItem where workflowItem = :workflowItem"; - Query query = createQuery(context, queryString); - query.setParameter("workflowItem", workflowItem); - query.executeUpdate(); - } - - @Override - public void deleteByWorkflowItemAndEPerson(Context context, BasicWorkflowItem workflowItem, EPerson ePerson) - throws SQLException { - String queryString = "delete from TaskListItem where workflowItem = :workflowItem AND ePerson = :ePerson"; - Query query = createQuery(context, queryString); - query.setParameter("workflowItem", workflowItem); - query.setParameter("ePerson", ePerson); - query.executeUpdate(); - } - - @Override - public void deleteByEPerson(Context context, EPerson ePerson) throws SQLException { - String queryString = "delete from TaskListItem where ePerson = :ePerson"; - Query query = createQuery(context, queryString); - query.setParameter("ePerson", ePerson); - query.executeUpdate(); - } - - @Override - public List findByEPerson(Context context, EPerson ePerson) throws SQLException { - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, TaskListItem.class); - Root taskListItemRoot = criteriaQuery.from(TaskListItem.class); - criteriaQuery.select(taskListItemRoot); - criteriaQuery.where(criteriaBuilder.equal(taskListItemRoot.get(TaskListItem_.ePerson), ePerson)); - return list(context, criteriaQuery, false, TaskListItem.class, -1, -1); - } -} diff --git a/dspace-api/src/main/java/org/dspace/workflowbasic/factory/BasicWorkflowServiceFactory.java b/dspace-api/src/main/java/org/dspace/workflowbasic/factory/BasicWorkflowServiceFactory.java deleted file mode 100644 index 22e5766ab5..0000000000 --- a/dspace-api/src/main/java/org/dspace/workflowbasic/factory/BasicWorkflowServiceFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.workflowbasic.factory; - -import org.dspace.services.factory.DSpaceServicesFactory; -import org.dspace.workflow.factory.WorkflowServiceFactory; -import org.dspace.workflowbasic.service.BasicWorkflowItemService; -import org.dspace.workflowbasic.service.BasicWorkflowService; -import org.dspace.workflowbasic.service.TaskListItemService; - -/** - * Abstract factory to get services for the workflowbasic package, use BasicWorkflowServiceFactory.getInstance() to - * retrieve an implementation - * - * @author kevinvandevelde at atmire.com - */ -public abstract class BasicWorkflowServiceFactory extends WorkflowServiceFactory { - - public abstract BasicWorkflowService getBasicWorkflowService(); - - public abstract BasicWorkflowItemService getBasicWorkflowItemService(); - - public abstract TaskListItemService getTaskListItemService(); - - public static BasicWorkflowServiceFactory getInstance() { - return DSpaceServicesFactory.getInstance().getServiceManager() - .getServiceByName("workflowServiceFactory", BasicWorkflowServiceFactory.class); - } -} diff --git a/dspace-api/src/main/java/org/dspace/workflowbasic/factory/BasicWorkflowServiceFactoryImpl.java b/dspace-api/src/main/java/org/dspace/workflowbasic/factory/BasicWorkflowServiceFactoryImpl.java deleted file mode 100644 index 839bdff3cc..0000000000 --- a/dspace-api/src/main/java/org/dspace/workflowbasic/factory/BasicWorkflowServiceFactoryImpl.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.workflowbasic.factory; - -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflow.WorkflowService; -import org.dspace.workflowbasic.service.BasicWorkflowItemService; -import org.dspace.workflowbasic.service.BasicWorkflowService; -import org.dspace.workflowbasic.service.TaskListItemService; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * Factory implementation to get services for the workflowbasic package, use BasicWorkflowServiceFactory.getInstance - * () to retrieve an implementation - * - * @author kevinvandevelde at atmire.com - */ -public class BasicWorkflowServiceFactoryImpl extends BasicWorkflowServiceFactory { - - @Autowired(required = true) - private BasicWorkflowService basicWorkflowService; - @Autowired(required = true) - private BasicWorkflowItemService basicWorkflowItemService; - @Autowired(required = true) - private TaskListItemService taskListItemService; - - - @Override - public BasicWorkflowService getBasicWorkflowService() { - return basicWorkflowService; - } - - @Override - public BasicWorkflowItemService getBasicWorkflowItemService() { - return basicWorkflowItemService; - } - - @Override - public TaskListItemService getTaskListItemService() { - return taskListItemService; - } - - @Override - public WorkflowService getWorkflowService() { - return getBasicWorkflowService(); - } - - @Override - public WorkflowItemService getWorkflowItemService() { - return getBasicWorkflowItemService(); - } -} diff --git a/dspace-api/src/main/java/org/dspace/workflowbasic/service/BasicWorkflowItemService.java b/dspace-api/src/main/java/org/dspace/workflowbasic/service/BasicWorkflowItemService.java deleted file mode 100644 index 9d0e8f82fd..0000000000 --- a/dspace-api/src/main/java/org/dspace/workflowbasic/service/BasicWorkflowItemService.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.workflowbasic.service; - -import java.sql.SQLException; -import java.util.List; - -import org.dspace.core.Context; -import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflowbasic.BasicWorkflowItem; - -/** - * Service interface class for the BasicWorkflowItem object. - * The implementation of this class is responsible for all business logic calls for the BasicWorkflowItem object and - * is autowired by spring - * - * @author kevinvandevelde at atmire.com - */ -public interface BasicWorkflowItemService extends WorkflowItemService { - - public List findPooledTasks(Context context, EPerson ePerson) throws SQLException; - - /** - * Retrieve the list of BasicWorkflowItems that the given EPerson is owner of (owner == claimed for review) - * - * @param context The relevant DSpace Context. - * @param ePerson The DSpace EPerson object. - * @return a list of BasicWorkflowItem objects - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - public List findByOwner(Context context, EPerson ePerson) throws SQLException; - - int countTotal(Context context) throws SQLException; -} diff --git a/dspace-api/src/main/java/org/dspace/workflowbasic/service/BasicWorkflowService.java b/dspace-api/src/main/java/org/dspace/workflowbasic/service/BasicWorkflowService.java deleted file mode 100644 index c1027b85f4..0000000000 --- a/dspace-api/src/main/java/org/dspace/workflowbasic/service/BasicWorkflowService.java +++ /dev/null @@ -1,206 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.workflowbasic.service; - -import java.io.IOException; -import java.sql.SQLException; -import java.util.List; - -import org.dspace.authorize.AuthorizeException; -import org.dspace.core.Context; -import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowService; -import org.dspace.workflowbasic.BasicWorkflowItem; - -/** - * Workflow state machine - * - * Notes: - * - * Determining item status from the database: - * - * When an item has not been submitted yet, it is in the user's personal - * workspace (there is a row in PersonalWorkspace pointing to it.) - * - * When an item is submitted and is somewhere in a workflow, it has a row in the - * WorkflowItem table pointing to it. The state of the workflow can be - * determined by looking at WorkflowItem.getState() - * - * When a submission is complete, the WorkflowItem pointing to the item is - * destroyed and the archive() method is called, which hooks the item up to the - * archive. - * - * Notification: When an item enters a state that requires notification, - * (WFSTATE_STEP1POOL, WFSTATE_STEP2POOL, WFSTATE_STEP3POOL,) the workflow needs - * to notify the appropriate groups that they have a pending task to claim. - * - * Revealing lists of approvers, editors, and reviewers. A method could be added - * to do this, but it isn't strictly necessary. (say public List - * getStateEPeople( WorkflowItem wi, int state ) could return people affected by - * the item's current state. - */ -public interface BasicWorkflowService extends WorkflowService { - - // states to store in WorkflowItem for the GUI to report on - // fits our current set of workflow states (stored in WorkflowItem.state) - public static final int WFSTATE_SUBMIT = 0; // hmm, probably don't need - - public static final int WFSTATE_STEP1POOL = 1; // waiting for a reviewer to - // claim it - - public static final int WFSTATE_STEP1 = 2; // task - reviewer has claimed it - - public static final int WFSTATE_STEP2POOL = 3; // waiting for an admin to - // claim it - - public static final int WFSTATE_STEP2 = 4; // task - admin has claimed item - - public static final int WFSTATE_STEP3POOL = 5; // waiting for an editor to - // claim it - - public static final int WFSTATE_STEP3 = 6; // task - editor has claimed the - // item - - public static final int WFSTATE_ARCHIVE = 7; // probably don't need this one - // either - - /** - * Translate symbolic name of workflow state into number. - * The name is case-insensitive. Returns -1 when name cannot - * be matched. - * - * @param state symbolic name of workflow state, must be one of - * the elements of workflowText array. - * @return numeric workflow state or -1 for error. - */ - public int getWorkflowID(String state); - - /** - * getOwnedTasks() returns a List of WorkflowItems containing the tasks - * claimed and owned by an EPerson. The GUI displays this info on the - * MyDSpace page. - * - * @param context The relevant DSpace Context. - * @param e The EPerson we want to fetch owned tasks for. - * @return list of basic workflow items - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - public List getOwnedTasks(Context context, EPerson e) - throws java.sql.SQLException; - - /** - * getPooledTasks() returns a List of WorkflowItems an EPerson could claim - * (as a reviewer, etc.) for display on a user's MyDSpace page. - * - * @param context The relevant DSpace Context. - * @param e The Eperson we want to fetch the pooled tasks for. - * @return list of basic workflow items - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - public List getPooledTasks(Context context, EPerson e) throws SQLException; - - /** - * claim() claims a workflow task for an EPerson - * - * @param context The relevant DSpace Context. - * @param workflowItem WorkflowItem to do the claim on - * @param e The EPerson doing the claim - * @throws SQLException An exception that provides information on a database access error or other errors. - * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. - * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. - */ - public void claim(Context context, BasicWorkflowItem workflowItem, EPerson e) - throws SQLException, IOException, AuthorizeException; - - - /** - * advance() sends an item forward in the workflow (reviewers, - * approvers, and editors all do an 'approve' to move the item forward) if - * the item arrives at the submit state, then remove the WorkflowItem and - * call the archive() method to put it in the archive, and email notify the - * submitter of a successful submission - * - * @param context The relevant DSpace Context. - * @param workflowItem WorkflowItem do do the approval on - * @param e EPerson doing the approval - * @throws SQLException An exception that provides information on a database access error or other errors. - * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. - * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. - */ - public void advance(Context context, BasicWorkflowItem workflowItem, EPerson e) - throws SQLException, IOException, AuthorizeException; - - /** - * advance() sends an item forward in the workflow (reviewers, - * approvers, and editors all do an 'approve' to move the item forward) if - * the item arrives at the submit state, then remove the WorkflowItem and - * call the archive() method to put it in the archive, and email notify the - * submitter of a successful submission - * - * @param context The relevant DSpace Context. - * @param workflowItem WorkflowItem do do the approval on - * @param e EPerson doing the approval - * @param curate boolean indicating whether curation tasks should be done - * @param record boolean indicating whether to record action - * @return true if the item was successfully archived - * @throws SQLException An exception that provides information on a database access error or other errors. - * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. - * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. - */ - public boolean advance(Context context, BasicWorkflowItem workflowItem, EPerson e, - boolean curate, boolean record) - throws SQLException, IOException, AuthorizeException; - - /** - * unclaim() returns an owned task/item to the pool - * - * @param context Context - * @param workflowItem WorkflowItem to operate on - * @param e EPerson doing the operation - * @throws SQLException An exception that provides information on a database access error or other errors. - * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. - * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. - */ - public void unclaim(Context context, BasicWorkflowItem workflowItem, EPerson e) - throws SQLException, IOException, AuthorizeException; - - /** - * Get the text representing the given workflow state - * - * @param state the workflow state - * @return the text representation - */ - public String getWorkflowText(int state); - - - // send notices of curation activity - public void notifyOfCuration(Context c, BasicWorkflowItem wi, List ePeople, - String taskName, String action, String message) throws SQLException, IOException; - - /** - * get the title of the item in this workflow - * - * @param wi the workflow item object - * @return item title - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - public String getItemTitle(BasicWorkflowItem wi) throws SQLException; - - /** - * get the name of the eperson who started this workflow - * - * @param wi the workflow item - * @return submitter's name - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - public String getSubmitterName(BasicWorkflowItem wi) throws SQLException; -} diff --git a/dspace-api/src/main/java/org/dspace/workflowbasic/service/TaskListItemService.java b/dspace-api/src/main/java/org/dspace/workflowbasic/service/TaskListItemService.java deleted file mode 100644 index 3a8aac65fe..0000000000 --- a/dspace-api/src/main/java/org/dspace/workflowbasic/service/TaskListItemService.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.workflowbasic.service; - -import java.sql.SQLException; -import java.util.List; - -import org.dspace.core.Context; -import org.dspace.eperson.EPerson; -import org.dspace.workflowbasic.BasicWorkflowItem; -import org.dspace.workflowbasic.TaskListItem; - -/** - * Service interface class for the TaskListItem object. - * The implementation of this class is responsible for all business logic calls for the TaskListItem object and is - * autowired by spring - * - * @author kevinvandevelde at atmire.com - */ -public interface TaskListItemService { - - public TaskListItem create(Context context, BasicWorkflowItem workflowItem, EPerson ePerson) throws SQLException; - - public void deleteByWorkflowItem(Context context, BasicWorkflowItem workflowItem) throws SQLException; - - public void deleteByWorkflowItemAndEPerson(Context context, BasicWorkflowItem workflowItem, EPerson ePerson) - throws SQLException; - - public void deleteByEPerson(Context context, EPerson ePerson) throws SQLException; - - public void update(Context context, TaskListItem taskListItem) throws SQLException; - - public List findByEPerson(Context context, EPerson ePerson) throws SQLException; -} diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/Role.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/Role.java index bfc5654cdd..03ad4b7935 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/Role.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/Role.java @@ -14,9 +14,9 @@ import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; import org.dspace.eperson.service.GroupService; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.CollectionRole; import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; import org.springframework.beans.factory.BeanNameAware; @@ -79,7 +79,7 @@ public class Role implements BeanNameAware { return scope; } - public RoleMembers getMembers(Context context, XmlWorkflowItem wfi) throws SQLException { + public RoleMembers getMembers(Context context, WorkflowItem wfi) throws SQLException { if (scope == Scope.REPOSITORY) { Group group = groupService.findByName(context, name); if (group == null) { diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowRequirementsServiceImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowRequirementsServiceImpl.java index c651097fcb..9111ff44f5 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowRequirementsServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowRequirementsServiceImpl.java @@ -17,17 +17,17 @@ import org.dspace.authorize.ResourcePolicy; import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.WorkflowService; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; -import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.storedcomponents.InProgressUser; import org.dspace.xmlworkflow.storedcomponents.PoolTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -52,22 +52,22 @@ public class WorkflowRequirementsServiceImpl implements WorkflowRequirementsServ @Autowired(required = true) protected XmlWorkflowFactory workflowFactory; @Autowired(required = true) - protected XmlWorkflowItemService xmlWorkflowItemService; + protected WorkflowItemService workflowItemService; @Autowired(required = true) - protected XmlWorkflowService xmlWorkflowService; + protected WorkflowService workflowService; protected WorkflowRequirementsServiceImpl() { } @Override - public void addClaimedUser(Context context, XmlWorkflowItem wfi, Step step, EPerson user) + public void addClaimedUser(Context context, WorkflowItem wfi, Step step, EPerson user) throws SQLException, AuthorizeException, IOException { //Make sure we delete the pooled task for our current user if the task is not a group pooltask PoolTask task = poolTaskService.findByWorkflowIdAndEPerson(context, wfi, user); if (task != null && task.getEperson() != null) { - xmlWorkflowService.deletePooledTask(context, wfi, task); + workflowService.deletePooledTask(context, wfi, task); } InProgressUser ipu = inProgressUserService.create(context); @@ -77,21 +77,21 @@ public class WorkflowRequirementsServiceImpl implements WorkflowRequirementsServ inProgressUserService.update(context, ipu); //Make sure the user has the necessary rights to update the item after the tasks is removed from the pool - xmlWorkflowService.grantUserAllItemPolicies(context, wfi.getItem(), user, ResourcePolicy.TYPE_WORKFLOW); + workflowService.grantUserAllItemPolicies(context, wfi.getItem(), user, ResourcePolicy.TYPE_WORKFLOW); int totalUsers = inProgressUserService.getNumberOfInProgressUsers(context, wfi) + inProgressUserService .getNumberOfFinishedUsers(context, wfi); if (totalUsers == step.getRequiredUsers()) { //If enough users have claimed/finished this step then remove the tasks - xmlWorkflowService.deleteAllPooledTasks(context, wfi); + workflowService.deleteAllPooledTasks(context, wfi); } - xmlWorkflowItemService.update(context, wfi); + workflowItemService.update(context, wfi); } @Override - public void removeClaimedUser(Context context, XmlWorkflowItem wfi, EPerson user, String stepID) + public void removeClaimedUser(Context context, WorkflowItem wfi, EPerson user, String stepID) throws SQLException, IOException, WorkflowConfigurationException, AuthorizeException { //Check if we had reached our max number @ this moment int totalUsers = inProgressUserService.getNumberOfInProgressUsers(context, wfi) + inProgressUserService @@ -101,7 +101,7 @@ public class WorkflowRequirementsServiceImpl implements WorkflowRequirementsServ inProgressUserService.delete(context, inProgressUserService.findByWorkflowItemAndEPerson(context, wfi, user)); //Make sure the removed user has his custom rights removed - xmlWorkflowService.removeUserItemPolicies(context, wfi.getItem(), user); + workflowService.removeUserItemPolicies(context, wfi.getItem(), user); Workflow workflow = workflowFactory.getWorkflow(wfi.getCollection()); Step step = workflow.getStep(stepID); @@ -142,7 +142,7 @@ public class WorkflowRequirementsServiceImpl implements WorkflowRequirementsServ } @Override - public void addFinishedUser(Context c, XmlWorkflowItem wfi, EPerson user) throws AuthorizeException, SQLException { + public void addFinishedUser(Context c, WorkflowItem wfi, EPerson user) throws AuthorizeException, SQLException { InProgressUser ipu = inProgressUserService.findByWorkflowItemAndEPerson(c, wfi, user); ipu.setFinished(true); inProgressUserService.update(c, ipu); @@ -150,7 +150,7 @@ public class WorkflowRequirementsServiceImpl implements WorkflowRequirementsServ @Override - public void clearInProgressUsers(Context c, XmlWorkflowItem wfi) throws AuthorizeException, SQLException { + public void clearInProgressUsers(Context c, WorkflowItem wfi) throws AuthorizeException, SQLException { Iterator ipus = inProgressUserService.findByWorkflowItem(c, wfi).iterator(); while (ipus.hasNext()) { InProgressUser ipu = ipus.next(); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/XmlWorkflowServiceImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowServiceImpl.java similarity index 94% rename from dspace-api/src/main/java/org/dspace/xmlworkflow/XmlWorkflowServiceImpl.java rename to dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowServiceImpl.java index e2ac626a6c..34f3446b2a 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/XmlWorkflowServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowServiceImpl.java @@ -54,9 +54,11 @@ import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.usage.UsageWorkflowEvent; import org.dspace.workflow.WorkflowException; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.WorkflowService; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; -import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.state.actions.Action; @@ -64,17 +66,15 @@ import org.dspace.xmlworkflow.state.actions.ActionResult; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.PoolTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** * When an item is submitted and is somewhere in a workflow, it has a row in the - * WorkflowItem table pointing to it. + * cwf_workflowitem table pointing to it. * * Once the item has completed the workflow it will be archived * @@ -83,12 +83,12 @@ import org.springframework.beans.factory.annotation.Autowired; * @author Ben Bosman (ben at atmire dot com) * @author Mark Diggory (markd at atmire dot com) */ -public class XmlWorkflowServiceImpl implements XmlWorkflowService { +public class WorkflowServiceImpl implements WorkflowService { /* support for 'no notification' */ protected Map noEMail = new HashMap<>(); - private final Logger log = org.apache.logging.log4j.LogManager.getLogger(XmlWorkflowServiceImpl.class); + private final Logger log = org.apache.logging.log4j.LogManager.getLogger(WorkflowServiceImpl.class); @Autowired(required = true) protected AuthorizeService authorizeService; @@ -113,7 +113,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { @Autowired(required = true) protected WorkspaceItemService workspaceItemService; @Autowired(required = true) - protected XmlWorkflowItemService xmlWorkflowItemService; + protected WorkflowItemService workflowItemService; @Autowired(required = true) protected GroupService groupService; @Autowired(required = true) @@ -125,7 +125,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { @Autowired(required = true) protected ConfigurationService configurationService; - protected XmlWorkflowServiceImpl() { + protected WorkflowServiceImpl() { } @@ -133,7 +133,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { @Override public void deleteCollection(Context context, Collection collection) throws SQLException, IOException, AuthorizeException { - xmlWorkflowItemService.deleteByCollection(context, collection); + workflowItemService.deleteByCollection(context, collection); collectionRoleService.deleteByCollection(context, collection); } @@ -194,18 +194,18 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { } @Override - public XmlWorkflowItem start(Context context, WorkspaceItem wsi) + public WorkflowItem start(Context context, WorkspaceItem wsi) throws SQLException, AuthorizeException, IOException, WorkflowException { try { Item myitem = wsi.getItem(); Collection collection = wsi.getCollection(); Workflow wf = xmlWorkflowFactory.getWorkflow(collection); - XmlWorkflowItem wfi = xmlWorkflowItemService.create(context, myitem, collection); + WorkflowItem wfi = workflowItemService.create(context, myitem, collection); wfi.setMultipleFiles(wsi.hasMultipleFiles()); wfi.setMultipleTitles(wsi.hasMultipleTitles()); wfi.setPublishedBefore(wsi.isPublishedBefore()); - xmlWorkflowItemService.update(context, wfi); + workflowItemService.update(context, wfi); removeUserItemPolicies(context, myitem, myitem.getSubmitter()); grantSubmitterReadPolicies(context, myitem); @@ -244,7 +244,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { * @param wsi the submitted Item entering workflow. */ @Override - public XmlWorkflowItem startWithoutNotify(Context context, WorkspaceItem wsi) + public WorkflowItem startWithoutNotify(Context context, WorkspaceItem wsi) throws SQLException, AuthorizeException, IOException, WorkflowException { // make a hash table entry with item ID for no notify // notify code checks no notify hash for item id @@ -254,7 +254,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { } @Override - public void alertUsersOnTaskActivation(Context c, XmlWorkflowItem wfi, String emailTemplate, List epa, + public void alertUsersOnTaskActivation(Context c, WorkflowItem wfi, String emailTemplate, List epa, String... arguments) throws IOException, SQLException, MessagingException { if (noEMail.containsKey(wfi.getItem().getID())) { // suppress email, and delete key @@ -292,7 +292,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { } - protected void activateFirstStep(Context context, Workflow wf, Step firstStep, XmlWorkflowItem wfi) + protected void activateFirstStep(Context context, Workflow wf, Step firstStep, WorkflowItem wfi) throws AuthorizeException, IOException, SQLException, WorkflowException, WorkflowConfigurationException { WorkflowActionConfig firstActionConfig = firstStep.getUserSelectionMethod(); firstActionConfig.getProcessingAction().activate(context, wfi); @@ -322,7 +322,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { Workflow workflow, WorkflowActionConfig currentActionConfig) throws SQLException, AuthorizeException, IOException, WorkflowException { try { - XmlWorkflowItem wi = xmlWorkflowItemService.find(c, workflowItemId); + WorkflowItem wi = workflowItemService.find(c, workflowItemId); Step currentStep = currentActionConfig.getStep(); if (currentActionConfig.getProcessingAction().isAuthorized(c, request, wi)) { ActionResult outcome = currentActionConfig.getProcessingAction().execute(c, wi, currentStep, request); @@ -349,7 +349,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { @Override public WorkflowActionConfig processOutcome(Context c, EPerson user, Workflow workflow, Step currentStep, WorkflowActionConfig currentActionConfig, ActionResult currentOutcome, - XmlWorkflowItem wfi, boolean enteredNewStep) + WorkflowItem wfi, boolean enteredNewStep) throws IOException, AuthorizeException, SQLException, WorkflowException { if (currentOutcome.getType() == ActionResult.TYPE.TYPE_PAGE || currentOutcome .getType() == ActionResult.TYPE.TYPE_ERROR) { @@ -460,7 +460,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { } protected void logWorkflowEvent(Context c, String workflowId, String previousStepId, String previousActionConfigId, - XmlWorkflowItem wfi, EPerson actor, Step newStep, + WorkflowItem wfi, EPerson actor, Step newStep, WorkflowActionConfig newActionConfig) throws SQLException { try { //Fire an event so we can log our action ! @@ -510,7 +510,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { } protected WorkflowActionConfig processNextStep(Context c, EPerson user, Workflow workflow, - ActionResult currentOutcome, XmlWorkflowItem wfi, Step nextStep) + ActionResult currentOutcome, WorkflowItem wfi, Step nextStep) throws SQLException, IOException, AuthorizeException, WorkflowException, WorkflowConfigurationException { WorkflowActionConfig nextActionConfig; if (nextStep != null) { @@ -552,7 +552,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { * @throws AuthorizeException Exception indicating the current user of the context does not have permission * to perform a particular action. */ - protected Item archive(Context context, XmlWorkflowItem wfi) + protected Item archive(Context context, WorkflowItem wfi) throws SQLException, IOException, AuthorizeException { // FIXME: Check auth Item item = wfi.getItem(); @@ -644,7 +644,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { * to perform a particular action. */ @Override - public void deleteAllTasks(Context context, XmlWorkflowItem wi) throws SQLException, AuthorizeException { + public void deleteAllTasks(Context context, WorkflowItem wi) throws SQLException, AuthorizeException { deleteAllPooledTasks(context, wi); Iterator allClaimedTasks = claimedTaskService.findByWorkflowItem(context, wi).iterator(); @@ -656,7 +656,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { } @Override - public void deleteAllPooledTasks(Context context, XmlWorkflowItem wi) throws SQLException, AuthorizeException { + public void deleteAllPooledTasks(Context context, WorkflowItem wi) throws SQLException, AuthorizeException { Iterator allPooledTasks = poolTaskService.find(context, wi).iterator(); while (allPooledTasks.hasNext()) { PoolTask poolTask = allPooledTasks.next(); @@ -669,7 +669,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { * Deletes an eperson from the taskpool of a step */ @Override - public void deletePooledTask(Context context, XmlWorkflowItem wi, PoolTask task) + public void deletePooledTask(Context context, WorkflowItem wi, PoolTask task) throws SQLException, AuthorizeException { if (task != null) { if (task.getEperson() != null) { @@ -682,7 +682,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { } @Override - public void deleteClaimedTask(Context c, XmlWorkflowItem wi, ClaimedTask task) + public void deleteClaimedTask(Context c, WorkflowItem wi, ClaimedTask task) throws SQLException, AuthorizeException { if (task != null) { removeUserItemPolicies(c, wi.getItem(), task.getOwner()); @@ -696,7 +696,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { * Creates a task pool for a given step */ @Override - public void createPoolTasks(Context context, XmlWorkflowItem wi, RoleMembers assignees, Step step, + public void createPoolTasks(Context context, WorkflowItem wi, RoleMembers assignees, Step step, WorkflowActionConfig action) throws SQLException, AuthorizeException { // create a tasklist entry for each eperson @@ -728,7 +728,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { * Claims an action for a given eperson */ @Override - public void createOwnedTask(Context context, XmlWorkflowItem wi, Step step, WorkflowActionConfig action, EPerson e) + public void createOwnedTask(Context context, WorkflowItem wi, Step step, WorkflowActionConfig action, EPerson e) throws SQLException, AuthorizeException { ClaimedTask task = claimedTaskService.create(context); task.setWorkflowItem(wi); @@ -875,7 +875,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { } @Override - public void deleteWorkflowByWorkflowItem(Context context, XmlWorkflowItem wi, EPerson e) + public void deleteWorkflowByWorkflowItem(Context context, WorkflowItem wi, EPerson e) throws SQLException, AuthorizeException, IOException { Item myitem = wi.getItem(); UUID itemID = myitem.getID(); @@ -889,7 +889,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { // Remove (if any) the workflowItemroles for this item workflowItemRoleService.deleteForWorkflowItem(context, wi); // Now remove the workflow object manually from the database - xmlWorkflowItemService.deleteWrapper(context, wi); + workflowItemService.deleteWrapper(context, wi); // Now delete the item itemService.delete(context, myitem); log.info(LogManager.getHeader(context, "delete_workflow", "workflow_item_id=" @@ -900,9 +900,9 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { } @Override - public WorkspaceItem sendWorkflowItemBackSubmission(Context context, XmlWorkflowItem wi, EPerson e, - String provenance, - String rejection_message) + public WorkspaceItem sendWorkflowItemBackSubmission(Context context, WorkflowItem wi, EPerson e, + String provenance, + String rejection_message) throws SQLException, AuthorizeException, IOException { @@ -962,7 +962,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { } @Override - public WorkspaceItem abort(Context c, XmlWorkflowItem wi, EPerson e) + public WorkspaceItem abort(Context c, WorkflowItem wi, EPerson e) throws AuthorizeException, SQLException, IOException { if (!authorizeService.isAdmin(c)) { throw new AuthorizeException( @@ -991,13 +991,13 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { * item is removed, and a workspace item created. * * @param c Context - * @param wfi WorkflowItem to be 'dismantled' + * @param wfi workflow item to be 'dismantled' * @return the workspace item * @throws java.io.IOException ... * @throws java.sql.SQLException ... * @throws org.dspace.authorize.AuthorizeException ... */ - protected WorkspaceItem returnToWorkspace(Context c, XmlWorkflowItem wfi) + protected WorkspaceItem returnToWorkspace(Context c, WorkflowItem wfi) throws SQLException, IOException, AuthorizeException { // authorize a DSpaceActions.REJECT // stop workflow @@ -1030,7 +1030,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { + workspaceItem.getID())); // Now remove the workflow object manually from the database - xmlWorkflowItemService.deleteWrapper(c, wfi); + workflowItemService.deleteWrapper(c, wfi); return workspaceItem; } @@ -1072,7 +1072,7 @@ public class XmlWorkflowServiceImpl implements XmlWorkflowService { itemService.update(context, myitem); } - protected void notifyOfReject(Context c, XmlWorkflowItem wi, EPerson e, + protected void notifyOfReject(Context c, WorkflowItem wi, EPerson e, String reason) { try { // send the notification only if the person was not deleted in the diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowUtils.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowUtils.java index 03cd105ca4..7e24e3e1cd 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowUtils.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowUtils.java @@ -32,8 +32,8 @@ import org.dspace.eperson.factory.EPersonServiceFactory; import org.dspace.eperson.service.GroupService; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.storedcomponents.CollectionRole; import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService; @@ -53,9 +53,9 @@ public class WorkflowUtils extends Util { public static Logger log = LogManager.getLogger(WorkflowUtils.class); protected static final CollectionRoleService collectionRoleService = - XmlWorkflowServiceFactory.getInstance().getCollectionRoleService(); + WorkflowServiceFactory.getInstance().getCollectionRoleService(); protected static final GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - protected static final XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance() + protected static final XmlWorkflowFactory xmlWorkflowFactory = WorkflowServiceFactory.getInstance() .getWorkflowFactory(); protected static final ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactory.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactory.java deleted file mode 100644 index 639a8d3770..0000000000 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactory.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.xmlworkflow.factory; - -import org.dspace.services.factory.DSpaceServicesFactory; -import org.dspace.workflow.factory.WorkflowServiceFactory; -import org.dspace.xmlworkflow.service.WorkflowRequirementsService; -import org.dspace.xmlworkflow.service.XmlWorkflowService; -import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; -import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService; -import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService; -import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; -import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; - -/** - * Abstract factory to get services for the xmlworkflow package, use XmlWorkflowServiceFactory.getInstance() to - * retrieve an implementation - * - * @author kevinvandevelde at atmire.com - */ -public abstract class XmlWorkflowServiceFactory extends WorkflowServiceFactory { - - public abstract XmlWorkflowFactory getWorkflowFactory(); - - public abstract WorkflowRequirementsService getWorkflowRequirementsService(); - - public abstract XmlWorkflowService getXmlWorkflowService(); - - public abstract ClaimedTaskService getClaimedTaskService(); - - public abstract CollectionRoleService getCollectionRoleService(); - - public abstract InProgressUserService getInProgressUserService(); - - public abstract PoolTaskService getPoolTaskService(); - - public abstract WorkflowItemRoleService getWorkflowItemRoleService(); - - public abstract XmlWorkflowItemService getXmlWorkflowItemService(); - - public static XmlWorkflowServiceFactory getInstance() { - return DSpaceServicesFactory.getInstance().getServiceManager() - .getServiceByName("workflowServiceFactory", XmlWorkflowServiceFactory.class); - } -} diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/service/WorkflowRequirementsService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/service/WorkflowRequirementsService.java index 29d29dbcda..ec102e2fca 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/service/WorkflowRequirementsService.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/service/WorkflowRequirementsService.java @@ -13,9 +13,9 @@ import java.sql.SQLException; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.Step; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * A class that contains utililty methods related to the workflow @@ -46,10 +46,10 @@ public interface WorkflowRequirementsService { * @throws AuthorizeException ... * @throws IOException ... */ - public void addClaimedUser(Context context, XmlWorkflowItem wfi, Step step, EPerson user) + public void addClaimedUser(Context context, WorkflowItem wfi, Step step, EPerson user) throws SQLException, AuthorizeException, IOException; - public void removeClaimedUser(Context context, XmlWorkflowItem wfi, EPerson user, String stepID) + public void removeClaimedUser(Context context, WorkflowItem wfi, EPerson user, String stepID) throws SQLException, IOException, WorkflowConfigurationException, AuthorizeException; /** @@ -62,8 +62,8 @@ public interface WorkflowRequirementsService { * @throws AuthorizeException ... * @throws SQLException ... */ - public void addFinishedUser(Context context, XmlWorkflowItem wfi, EPerson user) + public void addFinishedUser(Context context, WorkflowItem wfi, EPerson user) throws AuthorizeException, SQLException; - public void clearInProgressUsers(Context context, XmlWorkflowItem wfi) throws AuthorizeException, SQLException; + public void clearInProgressUsers(Context context, WorkflowItem wfi) throws AuthorizeException, SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/service/XmlWorkflowService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/service/XmlWorkflowService.java deleted file mode 100644 index f1f72b1b28..0000000000 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/service/XmlWorkflowService.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.xmlworkflow.service; - -import java.io.IOException; -import java.sql.SQLException; -import java.util.List; -import javax.mail.MessagingException; -import javax.servlet.http.HttpServletRequest; - -import org.dspace.authorize.AuthorizeException; -import org.dspace.content.Item; -import org.dspace.core.Context; -import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowException; -import org.dspace.workflow.WorkflowService; -import org.dspace.xmlworkflow.RoleMembers; -import org.dspace.xmlworkflow.state.Step; -import org.dspace.xmlworkflow.state.Workflow; -import org.dspace.xmlworkflow.state.actions.ActionResult; -import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; -import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; -import org.dspace.xmlworkflow.storedcomponents.PoolTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; - -/** - * When an item is submitted and is somewhere in a workflow, it has a row in the - * WorkflowItem table pointing to it. - * - * Once the item has completed the workflow it will be archived - * - * @author Bram De Schouwer (bram.deschouwer at dot com) - * @author Kevin Van de Velde (kevin at atmire dot com) - * @author Ben Bosman (ben at atmire dot com) - * @author Mark Diggory (markd at atmire dot com) - */ -public interface XmlWorkflowService extends WorkflowService { - - public void alertUsersOnTaskActivation(Context c, XmlWorkflowItem wfi, String emailTemplate, List epa, - String... arguments) throws IOException, SQLException, MessagingException; - - public WorkflowActionConfig doState(Context c, EPerson user, HttpServletRequest request, int workflowItemId, - Workflow workflow, WorkflowActionConfig currentActionConfig) - throws SQLException, AuthorizeException, IOException, MessagingException, WorkflowException; - - public WorkflowActionConfig processOutcome(Context c, EPerson user, Workflow workflow, Step currentStep, - WorkflowActionConfig currentActionConfig, ActionResult currentOutcome, - XmlWorkflowItem wfi, boolean enteredNewStep) - throws IOException, AuthorizeException, SQLException, WorkflowException; - - public void deleteAllTasks(Context context, XmlWorkflowItem wi) throws SQLException, AuthorizeException; - - public void deleteAllPooledTasks(Context c, XmlWorkflowItem wi) throws SQLException, AuthorizeException; - - public void deletePooledTask(Context context, XmlWorkflowItem wi, PoolTask task) - throws SQLException, AuthorizeException; - - public void deleteClaimedTask(Context c, XmlWorkflowItem wi, ClaimedTask task) - throws SQLException, AuthorizeException; - - public void createPoolTasks(Context context, XmlWorkflowItem wi, RoleMembers assignees, Step step, - WorkflowActionConfig action) - throws SQLException, AuthorizeException; - - public void createOwnedTask(Context context, XmlWorkflowItem wi, Step step, WorkflowActionConfig action, EPerson e) - throws SQLException, AuthorizeException; - - public void grantUserAllItemPolicies(Context context, Item item, EPerson epa, String actionType) - throws AuthorizeException, SQLException; - - public void removeUserItemPolicies(Context context, Item item, EPerson e) throws SQLException, AuthorizeException; - - public String getEPersonName(EPerson ePerson); -} diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Step.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Step.java index 813bee1d89..24633ebc23 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Step.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Step.java @@ -14,11 +14,11 @@ import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.dspace.core.Context; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.Role; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.annotation.Autowired; @@ -87,7 +87,7 @@ public class Step implements BeanNameAware { } - public boolean isValidStep(Context context, XmlWorkflowItem wfi) + public boolean isValidStep(Context context, WorkflowItem wfi) throws WorkflowConfigurationException, SQLException { //Check if our next step has a UI, if not then the step is valid, no need for a group return !(getUserSelectionMethod() == null || getUserSelectionMethod() @@ -125,7 +125,7 @@ public class Step implements BeanNameAware { * @return if enough users have finished this task * @throws SQLException An exception that provides information on a database access error or other errors. */ - public boolean isFinished(Context c, XmlWorkflowItem wfi) throws SQLException { + public boolean isFinished(Context c, WorkflowItem wfi) throws SQLException { return inProgressUserService.getNumberOfFinishedUsers(c, wfi) == requiredUsers; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Workflow.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Workflow.java index 935f3e0cbe..5e35eabbe5 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Workflow.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Workflow.java @@ -13,10 +13,10 @@ import java.util.List; import java.util.Map; import org.dspace.core.Context; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.Role; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.actions.ActionResult; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.annotation.Autowired; @@ -55,7 +55,7 @@ public class Workflow implements BeanNameAware { throw new WorkflowConfigurationException("Step definition not found for: " + stepID); } - public Step getNextStep(Context context, XmlWorkflowItem wfi, Step currentStep, int outcome) + public Step getNextStep(Context context, WorkflowItem wfi, Step currentStep, int outcome) throws WorkflowConfigurationException, SQLException { Step nextStep = currentStep.getNextStep(outcome); if (nextStep != null) { diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/Action.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/Action.java index c0c05b1745..c2fcf988e3 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/Action.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/Action.java @@ -16,10 +16,10 @@ import javax.servlet.http.HttpServletRequest; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.workflow.WorkflowException; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.Step; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * This abstract class represents an api action @@ -38,10 +38,10 @@ public abstract class Action { private WorkflowActionConfig parent; private static final String ERROR_FIELDS_ATTRIBUTE = "dspace.workflow.error_fields"; - public abstract void activate(Context c, XmlWorkflowItem wf) + public abstract void activate(Context c, WorkflowItem wf) throws SQLException, IOException, AuthorizeException, WorkflowException; - public abstract ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) + public abstract ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException, WorkflowException; /** @@ -76,12 +76,12 @@ public abstract class Action { return "Step: " + getParent().getStep().getId() + " - action:" + getParent().getId(); } - public void alertUsersOnActivation(Context c, XmlWorkflowItem wfi, RoleMembers members) + public void alertUsersOnActivation(Context c, WorkflowItem wfi, RoleMembers members) throws SQLException, IOException { } - public abstract boolean isAuthorized(Context context, HttpServletRequest request, XmlWorkflowItem wfi) + public abstract boolean isAuthorized(Context context, HttpServletRequest request, WorkflowItem wfi) throws SQLException, AuthorizeException, IOException, WorkflowConfigurationException; diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/AcceptEditRejectAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/AcceptEditRejectAction.java index 743d00b2b6..621e7678f1 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/AcceptEditRejectAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/AcceptEditRejectAction.java @@ -18,10 +18,10 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.content.DCDate; import org.dspace.content.MetadataSchemaEnum; import org.dspace.core.Context; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Processing class of an action that allows users to @@ -41,12 +41,12 @@ public class AcceptEditRejectAction extends ProcessingAction { //TODO: rename to AcceptAndEditMetadataAction @Override - public void activate(Context c, XmlWorkflowItem wf) { + public void activate(Context c, WorkflowItem wf) { } @Override - public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { if (super.isOptionInParam(request)) { switch (Util.getSubmitButton(request, SUBMIT_CANCEL)) { @@ -72,7 +72,7 @@ public class AcceptEditRejectAction extends ProcessingAction { return options; } - public ActionResult processAccept(Context c, XmlWorkflowItem wfi) + public ActionResult processAccept(Context c, WorkflowItem wfi) throws SQLException, AuthorizeException { //Delete the tasks addApprovedProvenance(c, wfi); @@ -80,7 +80,7 @@ public class AcceptEditRejectAction extends ProcessingAction { return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); } - public ActionResult processRejectPage(Context c, XmlWorkflowItem wfi, HttpServletRequest request) + public ActionResult processRejectPage(Context c, WorkflowItem wfi, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { String reason = request.getParameter("reason"); if (reason == null || 0 == reason.trim().length()) { @@ -90,16 +90,16 @@ public class AcceptEditRejectAction extends ProcessingAction { // We have pressed reject, so remove the task the user has & put it back // to a workspace item - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService().sendWorkflowItemBackSubmission(c, wfi, + WorkflowServiceFactory.getInstance().getWorkflowService().sendWorkflowItemBackSubmission(c, wfi, c.getCurrentUser(), this.getProvenanceStartId(), reason); return new ActionResult(ActionResult.TYPE.TYPE_SUBMISSION_PAGE); } - public ActionResult processSubmitterIsDeletedPage(Context c, XmlWorkflowItem wfi, HttpServletRequest request) + public ActionResult processSubmitterIsDeletedPage(Context c, WorkflowItem wfi, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { if (request.getParameter("submit_delete") != null) { - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() + WorkflowServiceFactory.getInstance().getWorkflowService() .deleteWorkflowByWorkflowItem(c, wfi, c.getCurrentUser()); // Delete and send user back to myDspace page return new ActionResult(ActionResult.TYPE.TYPE_SUBMISSION_PAGE); @@ -112,12 +112,12 @@ public class AcceptEditRejectAction extends ProcessingAction { } } - private void addApprovedProvenance(Context c, XmlWorkflowItem wfi) throws SQLException, AuthorizeException { + private void addApprovedProvenance(Context c, WorkflowItem wfi) throws SQLException, AuthorizeException { //Add the provenance for the accept String now = DCDate.getCurrent().toString(); // Get user's name + email address - String usersName = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() + String usersName = WorkflowServiceFactory.getInstance().getWorkflowService() .getEPersonName(c.getCurrentUser()); String provDescription = getProvenanceStartId() + " Approved for entry into archive by " diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/FinalEditAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/FinalEditAction.java index 3c4e0ffc1d..1a35d90d6a 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/FinalEditAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/FinalEditAction.java @@ -17,10 +17,10 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.content.DCDate; import org.dspace.content.MetadataSchemaEnum; import org.dspace.core.Context; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Processing class of an action that allows users to @@ -36,17 +36,17 @@ public class FinalEditAction extends ProcessingAction { private static final String SUBMIT_APPROVE = "submit_approve"; @Override - public void activate(Context c, XmlWorkflowItem wf) { + public void activate(Context c, WorkflowItem wf) { } @Override - public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException { return processMainPage(c, wfi, request); } - public ActionResult processMainPage(Context c, XmlWorkflowItem wfi, HttpServletRequest request) + public ActionResult processMainPage(Context c, WorkflowItem wfi, HttpServletRequest request) throws SQLException, AuthorizeException { if (super.isOptionInParam(request)) { switch (Util.getSubmitButton(request, SUBMIT_CANCEL)) { @@ -70,12 +70,12 @@ public class FinalEditAction extends ProcessingAction { return options; } - private void addApprovedProvenance(Context c, XmlWorkflowItem wfi) throws SQLException, AuthorizeException { + private void addApprovedProvenance(Context c, WorkflowItem wfi) throws SQLException, AuthorizeException { //Add the provenance for the accept String now = DCDate.getCurrent().toString(); // Get user's name + email address - String usersName = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() + String usersName = WorkflowServiceFactory.getInstance().getWorkflowService() .getEPersonName(c.getCurrentUser()); String provDescription = getProvenanceStartId() + " Approved for entry into archive by " diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ProcessingAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ProcessingAction.java index 76e5cb5e9f..7ae5c5e350 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ProcessingAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ProcessingAction.java @@ -12,9 +12,9 @@ import javax.servlet.http.HttpServletRequest; import org.dspace.content.service.ItemService; import org.dspace.core.Context; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.state.actions.Action; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.springframework.beans.factory.annotation.Autowired; @@ -38,7 +38,7 @@ public abstract class ProcessingAction extends Action { public static final String SUBMIT_CANCEL = "submit_cancel"; @Override - public boolean isAuthorized(Context context, HttpServletRequest request, XmlWorkflowItem wfi) throws SQLException { + public boolean isAuthorized(Context context, HttpServletRequest request, WorkflowItem wfi) throws SQLException { ClaimedTask task = null; if (context.getCurrentUser() != null) { task = claimedTaskService.findByWorkflowIdAndEPerson(context, wfi, context.getCurrentUser()); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ReviewAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ReviewAction.java index 8474757be6..11fe8e574e 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ReviewAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ReviewAction.java @@ -18,10 +18,10 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.content.DCDate; import org.dspace.content.MetadataSchemaEnum; import org.dspace.core.Context; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Processing class of an accept/reject action @@ -42,12 +42,12 @@ public class ReviewAction extends ProcessingAction { @Override - public void activate(Context c, XmlWorkflowItem wfItem) { + public void activate(Context c, WorkflowItem wfItem) { } @Override - public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { if (super.isOptionInParam(request)) { switch (Util.getSubmitButton(request, SUBMIT_CANCEL)) { @@ -72,18 +72,18 @@ public class ReviewAction extends ProcessingAction { return options; } - public ActionResult processAccept(Context c, XmlWorkflowItem wfi) throws SQLException, AuthorizeException { + public ActionResult processAccept(Context c, WorkflowItem wfi) throws SQLException, AuthorizeException { //Delete the tasks addApprovedProvenance(c, wfi); return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); } - private void addApprovedProvenance(Context c, XmlWorkflowItem wfi) throws SQLException, AuthorizeException { + private void addApprovedProvenance(Context c, WorkflowItem wfi) throws SQLException, AuthorizeException { //Add the provenance for the accept String now = DCDate.getCurrent().toString(); // Get user's name + email address - String usersName = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() + String usersName = WorkflowServiceFactory.getInstance().getWorkflowService() .getEPersonName(c.getCurrentUser()); String provDescription = getProvenanceStartId() + " Approved for entry into archive by " @@ -95,7 +95,7 @@ public class ReviewAction extends ProcessingAction { itemService.update(c, wfi.getItem()); } - public ActionResult processRejectPage(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult processRejectPage(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { String reason = request.getParameter("reason"); if (reason == null || 0 == reason.trim().length()) { @@ -105,7 +105,7 @@ public class ReviewAction extends ProcessingAction { } //We have pressed reject, so remove the task the user has & put it back to a workspace item - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() + WorkflowServiceFactory.getInstance().getWorkflowService() .sendWorkflowItemBackSubmission(c, wfi, c.getCurrentUser(), this.getProvenanceStartId(), reason); @@ -113,10 +113,10 @@ public class ReviewAction extends ProcessingAction { return new ActionResult(ActionResult.TYPE.TYPE_SUBMISSION_PAGE); } - public ActionResult processSubmitterIsDeletedPage(Context c, XmlWorkflowItem wfi, HttpServletRequest request) + public ActionResult processSubmitterIsDeletedPage(Context c, WorkflowItem wfi, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { if (request.getParameter("submit_delete") != null) { - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() + WorkflowServiceFactory.getInstance().getWorkflowService() .deleteWorkflowByWorkflowItem(c, wfi, c.getCurrentUser()); // Delete and send user back to myDspace page return new ActionResult(ActionResult.TYPE.TYPE_SUBMISSION_PAGE); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreEvaluationAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreEvaluationAction.java index a834641111..94ac8266b6 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreEvaluationAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreEvaluationAction.java @@ -18,11 +18,11 @@ import org.dspace.content.Item; import org.dspace.content.MetadataSchemaEnum; import org.dspace.content.MetadataValue; import org.dspace.core.Context; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Processing class for the score evaluation action @@ -40,12 +40,12 @@ public class ScoreEvaluationAction extends ProcessingAction { private int minimumAcceptanceScore; @Override - public void activate(Context c, XmlWorkflowItem wf) { + public void activate(Context c, WorkflowItem wf) { } @Override - public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { boolean hasPassed = false; //Retrieve all our scores from the metadata & add em up @@ -73,7 +73,7 @@ public class ScoreEvaluationAction extends ProcessingAction { return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); } else { //We haven't passed, reject our item - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() + WorkflowServiceFactory.getInstance().getWorkflowService() .sendWorkflowItemBackSubmission(c, wfi, c.getCurrentUser(), this.getProvenanceStartId(), "The item was reject due to a bad review score."); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java index c28fe2d93e..93c320d185 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java @@ -15,10 +15,10 @@ import javax.servlet.http.HttpServletRequest; import org.dspace.app.util.Util; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * This action will allow multiple users to rate a certain item @@ -35,12 +35,12 @@ public class ScoreReviewAction extends ProcessingAction { private static final String SUBMIT_SCORE = "submit_score"; @Override - public void activate(Context c, XmlWorkflowItem wf) { + public void activate(Context c, WorkflowItem wf) { } @Override - public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException { if (request.getParameter(SUBMIT_SCORE) != null) { int score = Util.getIntParameter(request, "score"); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SelectReviewerAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SelectReviewerAction.java index 16a8777275..7651a8bf58 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SelectReviewerAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SelectReviewerAction.java @@ -18,11 +18,11 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.service.EPersonService; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.Role; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; import org.springframework.beans.factory.annotation.Autowired; @@ -54,12 +54,12 @@ public class SelectReviewerAction extends ProcessingAction { private WorkflowItemRoleService workflowItemRoleService; @Override - public void activate(Context c, XmlWorkflowItem wf) { + public void activate(Context c, WorkflowItem wf) { } @Override - public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException { String submitButton = Util.getSubmitButton(request, SUBMIT_CANCEL); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java index 9ef554821d..c3e251ed4b 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java @@ -18,10 +18,10 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.content.DCDate; import org.dspace.content.MetadataSchemaEnum; import org.dspace.core.Context; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Processing class of an action where a single user has @@ -46,12 +46,12 @@ public class SingleUserReviewAction extends ProcessingAction { protected static final String SUBMIT_DECLINE_TASK = "submit_decline_task"; @Override - public void activate(Context c, XmlWorkflowItem wfItem) { + public void activate(Context c, WorkflowItem wfItem) { } @Override - public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { int page = Util.getIntParameter(request, "page"); @@ -76,7 +76,7 @@ public class SingleUserReviewAction extends ProcessingAction { return options; } - public ActionResult processMainPage(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult processMainPage(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException { if (request.getParameter(SUBMIT_APPROVE) != null) { //Delete the tasks @@ -101,12 +101,12 @@ public class SingleUserReviewAction extends ProcessingAction { } } - private void addApprovedProvenance(Context c, XmlWorkflowItem wfi) throws SQLException, AuthorizeException { + private void addApprovedProvenance(Context c, WorkflowItem wfi) throws SQLException, AuthorizeException { //Add the provenance for the accept String now = DCDate.getCurrent().toString(); // Get user's name + email address - String usersName = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() + String usersName = WorkflowServiceFactory.getInstance().getWorkflowService() .getEPersonName(c.getCurrentUser()); String provDescription = getProvenanceStartId() + " Approved for entry into archive by " @@ -118,7 +118,7 @@ public class SingleUserReviewAction extends ProcessingAction { itemService.update(c, wfi.getItem()); } - public ActionResult processRejectPage(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult processRejectPage(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { if (request.getParameter("submit_reject") != null) { String reason = request.getParameter("reason"); @@ -129,7 +129,7 @@ public class SingleUserReviewAction extends ProcessingAction { } //We have pressed reject, so remove the task the user has & put it back to a workspace item - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() + WorkflowServiceFactory.getInstance().getWorkflowService() .sendWorkflowItemBackSubmission(c, wfi, c.getCurrentUser(), this.getProvenanceStartId(), reason); @@ -143,10 +143,10 @@ public class SingleUserReviewAction extends ProcessingAction { } } - public ActionResult processSubmitterIsDeletedPage(Context c, XmlWorkflowItem wfi, HttpServletRequest request) + public ActionResult processSubmitterIsDeletedPage(Context c, WorkflowItem wfi, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { if (request.getParameter("submit_delete") != null) { - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() + WorkflowServiceFactory.getInstance().getWorkflowService() .deleteWorkflowByWorkflowItem(c, wfi, c.getCurrentUser()); // Delete and send user back to myDspace page return new ActionResult(ActionResult.TYPE.TYPE_SUBMISSION_PAGE); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignAction.java index e837a8a893..b4a93edb59 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignAction.java @@ -13,11 +13,11 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import org.dspace.core.Context; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * @author Bram De Schouwer (bram.deschouwer at dot com) @@ -28,11 +28,11 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; public class AssignAction extends UserSelectionAction { @Override - public void activate(Context c, XmlWorkflowItem wfItem) { + public void activate(Context c, WorkflowItem wfItem) { } @Override - public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) { + public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) { return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); } @@ -45,16 +45,16 @@ public class AssignAction extends UserSelectionAction { } @Override - public boolean isFinished(XmlWorkflowItem wfi) { + public boolean isFinished(WorkflowItem wfi) { return false; } @Override - public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) throws SQLException { + public void regenerateTasks(Context c, WorkflowItem wfi, RoleMembers roleMembers) throws SQLException { } @Override - public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) + public boolean isValidUserSelection(Context context, WorkflowItem wfi, boolean hasUI) throws WorkflowConfigurationException, SQLException { return false; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignOriginalSubmitterAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignOriginalSubmitterAction.java index 3c8d85997a..b979ab6046 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignOriginalSubmitterAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignOriginalSubmitterAction.java @@ -20,15 +20,15 @@ import org.dspace.core.Context; import org.dspace.core.LogManager; import org.dspace.eperson.EPerson; import org.dspace.workflow.WorkflowException; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowService; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; -import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.springframework.beans.factory.annotation.Autowired; /** @@ -46,17 +46,17 @@ public class AssignOriginalSubmitterAction extends UserSelectionAction { protected WorkflowRequirementsService workflowRequirementsService; @Override - public boolean isFinished(XmlWorkflowItem wfi) { + public boolean isFinished(WorkflowItem wfi) { return false; } @Override - public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) throws SQLException { + public void regenerateTasks(Context c, WorkflowItem wfi, RoleMembers roleMembers) throws SQLException { } @Override - public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) + public boolean isValidUserSelection(Context context, WorkflowItem wfi, boolean hasUI) throws WorkflowConfigurationException, SQLException { return wfi.getSubmitter() != null; } @@ -67,24 +67,24 @@ public class AssignOriginalSubmitterAction extends UserSelectionAction { } @Override - public void activate(Context c, XmlWorkflowItem wf) throws SQLException, IOException { + public void activate(Context c, WorkflowItem wf) throws SQLException, IOException { } @Override - public void alertUsersOnActivation(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) + public void alertUsersOnActivation(Context c, WorkflowItem wfi, RoleMembers roleMembers) throws IOException, SQLException { if (wfi.getSubmitter() != null) { try { - XmlWorkflowService xmlWorkflowService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); - xmlWorkflowService.alertUsersOnTaskActivation(c, wfi, "submit_task", Arrays.asList(wfi.getSubmitter()), + WorkflowService workflowService = WorkflowServiceFactory.getInstance().getWorkflowService(); + workflowService.alertUsersOnTaskActivation(c, wfi, "submit_task", Arrays.asList(wfi.getSubmitter()), //The arguments wfi.getItem().getName(), wfi.getCollection().getName(), wfi.getSubmitter().getFullName(), //TODO: message "New task available.", - xmlWorkflowService.getMyDSpaceLink() + workflowService.getMyDSpaceLink() ); } catch (MessagingException e) { log.info(LogManager.getHeader(c, "error emailing user(s) for claimed task", @@ -95,7 +95,7 @@ public class AssignOriginalSubmitterAction extends UserSelectionAction { @Override - public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException, WorkflowException { EPerson submitter = wfi.getSubmitter(); WorkflowActionConfig nextAction = getParent().getStep().getNextAction(this.getParent()); @@ -133,11 +133,11 @@ public class AssignOriginalSubmitterAction extends UserSelectionAction { * @throws AuthorizeException ... * @throws IOException ... */ - protected void createTaskForEPerson(Context c, XmlWorkflowItem wfi, Step step, WorkflowActionConfig actionConfig, + protected void createTaskForEPerson(Context c, WorkflowItem wfi, Step step, WorkflowActionConfig actionConfig, EPerson user) throws SQLException, AuthorizeException, IOException { if (claimedTaskService.find(c, wfi, step.getId(), actionConfig.getId()) != null) { workflowRequirementsService.addClaimedUser(c, wfi, step, c.getCurrentUser()); - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() + WorkflowServiceFactory.getInstance().getWorkflowService() .createOwnedTask(c, wfi, step, actionConfig, user); } } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AutoAssignAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AutoAssignAction.java index 3f87c26029..f46a3cc2bd 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AutoAssignAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AutoAssignAction.java @@ -19,16 +19,16 @@ import org.dspace.core.Context; import org.dspace.core.LogManager; import org.dspace.eperson.EPerson; import org.dspace.eperson.service.GroupService; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.Role; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.springframework.beans.factory.annotation.Autowired; /** @@ -51,12 +51,12 @@ public class AutoAssignAction extends UserSelectionAction { protected WorkflowRequirementsService workflowRequirementsService; @Override - public void activate(Context c, XmlWorkflowItem wfItem) { + public void activate(Context c, WorkflowItem wfItem) { } @Override - public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { try { Role role = getParent().getStep().getRole(); @@ -124,27 +124,27 @@ public class AutoAssignAction extends UserSelectionAction { * @throws AuthorizeException ... * @throws IOException ... */ - protected void createTaskForEPerson(Context c, XmlWorkflowItem wfi, Step step, WorkflowActionConfig actionConfig, + protected void createTaskForEPerson(Context c, WorkflowItem wfi, Step step, WorkflowActionConfig actionConfig, EPerson user) throws SQLException, AuthorizeException, IOException { if (claimedTaskService.find(c, wfi, step.getId(), actionConfig.getId()) != null) { workflowRequirementsService.addClaimedUser(c, wfi, step, c.getCurrentUser()); - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() + WorkflowServiceFactory.getInstance().getWorkflowService() .createOwnedTask(c, wfi, step, actionConfig, user); } } @Override - public boolean isFinished(XmlWorkflowItem wfi) { + public boolean isFinished(WorkflowItem wfi) { return true; } @Override - public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) throws SQLException { + public void regenerateTasks(Context c, WorkflowItem wfi, RoleMembers roleMembers) throws SQLException { } @Override - public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) + public boolean isValidUserSelection(Context context, WorkflowItem wfi, boolean hasUI) throws WorkflowConfigurationException, SQLException { //This is an automatic assign action, it can never have a user interface Role role = getParent().getStep().getRole(); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/ClaimAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/ClaimAction.java index 744bf69136..9ea7261d59 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/ClaimAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/ClaimAction.java @@ -20,14 +20,14 @@ import org.dspace.core.LogManager; import org.dspace.eperson.EPerson; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowService; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.Role; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; -import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Processing class for an action where x number of users @@ -43,14 +43,14 @@ public class ClaimAction extends UserSelectionAction { = DSpaceServicesFactory.getInstance().getConfigurationService(); @Override - public void activate(Context context, XmlWorkflowItem wfItem) throws SQLException, IOException, AuthorizeException { + public void activate(Context context, WorkflowItem wfItem) throws SQLException, IOException, AuthorizeException { Step owningStep = getParent().getStep(); RoleMembers allroleMembers = getParent().getStep().getRole().getMembers(context, wfItem); // Create pooled tasks for each member of our group if (allroleMembers != null && (allroleMembers.getGroups().size() > 0 || allroleMembers.getEPersons() .size() > 0)) { - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() + WorkflowServiceFactory.getInstance().getWorkflowService() .createPoolTasks(context, wfItem, allroleMembers, owningStep, getParent()); alertUsersOnActivation(context, wfItem, allroleMembers); } else { @@ -63,10 +63,10 @@ public class ClaimAction extends UserSelectionAction { } @Override - public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { // accept task, or accepting multiple tasks - XmlWorkflowServiceFactory.getInstance().getWorkflowRequirementsService().addClaimedUser(c, wfi, step, + WorkflowServiceFactory.getInstance().getWorkflowRequirementsService().addClaimedUser(c, wfi, step, c.getCurrentUser()); return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); } @@ -77,7 +77,7 @@ public class ClaimAction extends UserSelectionAction { } @Override - public void alertUsersOnActivation(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) + public void alertUsersOnActivation(Context c, WorkflowItem wfi, RoleMembers roleMembers) throws IOException, SQLException { try { EPerson ep = wfi.getSubmitter(); @@ -85,15 +85,15 @@ public class ClaimAction extends UserSelectionAction { if (ep != null) { submitterName = ep.getFullName(); } - XmlWorkflowService xmlWorkflowService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); - xmlWorkflowService.alertUsersOnTaskActivation(c, wfi, "submit_task", roleMembers.getAllUniqueMembers(c), + WorkflowService workflowService = WorkflowServiceFactory.getInstance().getWorkflowService(); + workflowService.alertUsersOnTaskActivation(c, wfi, "submit_task", roleMembers.getAllUniqueMembers(c), //The arguments wfi.getItem().getName(), wfi.getCollection().getName(), submitterName, //TODO: message "New task available.", - xmlWorkflowService.getMyDSpaceLink() + workflowService.getMyDSpaceLink() ); } catch (MessagingException e) { log.info(LogManager.getHeader(c, "error emailing user(s) for claimed task", @@ -102,11 +102,11 @@ public class ClaimAction extends UserSelectionAction { } @Override - public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) + public void regenerateTasks(Context c, WorkflowItem wfi, RoleMembers roleMembers) throws SQLException, AuthorizeException, IOException { if (roleMembers != null && (roleMembers.getEPersons().size() > 0 || roleMembers.getGroups().size() > 0)) { //Create task for the users left - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() + WorkflowServiceFactory.getInstance().getWorkflowService() .createPoolTasks(c, wfi, roleMembers, getParent().getStep(), getParent()); if (configurationService.getBooleanProperty("workflow.notify.returned.tasks", true)) { alertUsersOnActivation(c, wfi, roleMembers); @@ -121,12 +121,12 @@ public class ClaimAction extends UserSelectionAction { } @Override - public boolean isFinished(XmlWorkflowItem wfi) { + public boolean isFinished(WorkflowItem wfi) { return false; } @Override - public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) + public boolean isValidUserSelection(Context context, WorkflowItem wfi, boolean hasUI) throws WorkflowConfigurationException, SQLException { //A user claim action always needs to have a UI, since somebody needs to be able to claim it if (hasUI) { diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/InheritUsersAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/InheritUsersAction.java index 1ffce1afdb..422c03218b 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/InheritUsersAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/InheritUsersAction.java @@ -13,11 +13,11 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import org.dspace.core.Context; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * A user selection action that inherits user @@ -31,11 +31,11 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; public class InheritUsersAction extends UserSelectionAction { @Override - public void activate(Context c, XmlWorkflowItem wfItem) { + public void activate(Context c, WorkflowItem wfItem) { } @Override - public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) { + public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) { return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); } @@ -45,16 +45,16 @@ public class InheritUsersAction extends UserSelectionAction { } @Override - public boolean isFinished(XmlWorkflowItem wfi) { + public boolean isFinished(WorkflowItem wfi) { return false; } @Override - public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) throws SQLException { + public void regenerateTasks(Context c, WorkflowItem wfi, RoleMembers roleMembers) throws SQLException { } @Override - public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) + public boolean isValidUserSelection(Context context, WorkflowItem wfi, boolean hasUI) throws WorkflowConfigurationException, SQLException { return false; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/NoUserSelectionAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/NoUserSelectionAction.java index d23a98cedb..98e1ede2a4 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/NoUserSelectionAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/NoUserSelectionAction.java @@ -12,10 +12,10 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import org.dspace.core.Context; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * A user selection action that does not assign any users @@ -27,16 +27,16 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; */ public class NoUserSelectionAction extends UserSelectionAction { @Override - public boolean isFinished(XmlWorkflowItem wfi) { + public boolean isFinished(WorkflowItem wfi) { return true; } @Override - public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) { + public void regenerateTasks(Context c, WorkflowItem wfi, RoleMembers roleMembers) { } @Override - public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) { + public boolean isValidUserSelection(Context context, WorkflowItem wfi, boolean hasUI) { return true; } @@ -46,11 +46,11 @@ public class NoUserSelectionAction extends UserSelectionAction { } @Override - public void activate(Context c, XmlWorkflowItem wf) { + public void activate(Context c, WorkflowItem wf) { } @Override - public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) { + public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) { return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/UserSelectionAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/UserSelectionAction.java index bbeb7cd173..0896700eb2 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/UserSelectionAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/UserSelectionAction.java @@ -14,11 +14,11 @@ import javax.servlet.http.HttpServletRequest; import org.apache.logging.log4j.Logger; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.actions.Action; import org.dspace.xmlworkflow.storedcomponents.PoolTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; @@ -38,7 +38,7 @@ public abstract class UserSelectionAction extends Action { protected Logger log = org.apache.logging.log4j.LogManager.getLogger(UserSelectionAction.class); - public abstract boolean isFinished(XmlWorkflowItem wfi); + public abstract boolean isFinished(WorkflowItem wfi); @Autowired(required = true) protected ClaimedTaskService claimedTaskService; @@ -48,7 +48,7 @@ public abstract class UserSelectionAction extends Action { protected WorkflowItemRoleService workflowItemRoleService; @Override - public boolean isAuthorized(Context context, HttpServletRequest request, XmlWorkflowItem wfi) + public boolean isAuthorized(Context context, HttpServletRequest request, WorkflowItem wfi) throws SQLException, AuthorizeException, IOException, WorkflowConfigurationException { PoolTask task = null; if (context.getCurrentUser() != null) { @@ -72,7 +72,7 @@ public abstract class UserSelectionAction extends Action { * @throws SQLException An exception that provides information on a database access error or other errors. * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. */ - public abstract void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) + public abstract void regenerateTasks(Context c, WorkflowItem wfi, RoleMembers roleMembers) throws SQLException, AuthorizeException, IOException; /** @@ -87,7 +87,7 @@ public abstract class UserSelectionAction extends Action { * @throws SQLException An exception that provides information on a database access error or * other errors. */ - public abstract boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) + public abstract boolean isValidUserSelection(Context context, WorkflowItem wfi, boolean hasUI) throws WorkflowConfigurationException, SQLException; /** diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTask.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTask.java index 8882055f82..3dd087289f 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTask.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTask.java @@ -21,6 +21,7 @@ import javax.persistence.Table; import org.dspace.core.Context; import org.dspace.core.ReloadableEntity; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; /** * Claimed task representing the database representation of an action claimed by an eperson @@ -42,7 +43,7 @@ public class ClaimedTask implements ReloadableEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "workflowitem_id") - private XmlWorkflowItem workflowItem; + private WorkflowItem workflowItem; // @Column(name = "workflow_id") // @Lob @@ -83,11 +84,11 @@ public class ClaimedTask implements ReloadableEntity { return owner; } - public void setWorkflowItem(XmlWorkflowItem workflowItem) { + public void setWorkflowItem(WorkflowItem workflowItem) { this.workflowItem = workflowItem; } - public XmlWorkflowItem getWorkflowItem() { + public WorkflowItem getWorkflowItem() { return workflowItem; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTaskServiceImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTaskServiceImpl.java index 4bed9cdbf0..22497705fa 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTaskServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTaskServiceImpl.java @@ -16,6 +16,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.ClaimedTaskDAO; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.springframework.beans.factory.annotation.Autowired; @@ -71,12 +72,12 @@ public class ClaimedTaskServiceImpl implements ClaimedTaskService { } @Override - public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException { + public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException { return claimedTaskDAO.findByWorkflowItem(context, workflowItem); } @Override - public ClaimedTask findByWorkflowIdAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) + public ClaimedTask findByWorkflowIdAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) throws SQLException { return claimedTaskDAO.findByWorkflowItemAndEPerson(context, workflowItem, ePerson); } @@ -87,25 +88,25 @@ public class ClaimedTaskServiceImpl implements ClaimedTaskService { } @Override - public List find(Context context, XmlWorkflowItem workflowItem, String stepID) throws SQLException { + public List find(Context context, WorkflowItem workflowItem, String stepID) throws SQLException { return claimedTaskDAO.findByWorkflowItemAndStepId(context, workflowItem, stepID); } @Override - public ClaimedTask find(Context context, EPerson ePerson, XmlWorkflowItem workflowItem, String stepID, + public ClaimedTask find(Context context, EPerson ePerson, WorkflowItem workflowItem, String stepID, String actionID) throws SQLException { return claimedTaskDAO .findByEPersonAndWorkflowItemAndStepIdAndActionId(context, ePerson, workflowItem, stepID, actionID); } @Override - public List find(Context context, XmlWorkflowItem workflowItem, String stepID, String actionID) + public List find(Context context, WorkflowItem workflowItem, String stepID, String actionID) throws SQLException { return claimedTaskDAO.findByWorkflowItemAndStepIdAndActionId(context, workflowItem, stepID, actionID); } @Override - public List find(Context context, XmlWorkflowItem workflowItem) throws SQLException { + public List find(Context context, WorkflowItem workflowItem) throws SQLException { return claimedTaskDAO.findByWorkflowItem(context, workflowItem); } @@ -115,7 +116,7 @@ public class ClaimedTaskServiceImpl implements ClaimedTaskService { } @Override - public void deleteByWorkflowItem(Context context, XmlWorkflowItem workflowItem) + public void deleteByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException, AuthorizeException { List claimedTasks = findByWorkflowItem(context, workflowItem); //Use an iterator to remove the tasks ! diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUser.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUser.java index 5cd714345e..2bb59c378d 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUser.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUser.java @@ -21,6 +21,7 @@ import javax.persistence.Table; import org.dspace.core.Context; import org.dspace.core.ReloadableEntity; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; /** * Claimed task representing the database representation of an action claimed by an eperson @@ -46,7 +47,7 @@ public class InProgressUser implements ReloadableEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "workflowitem_id") - private XmlWorkflowItem workflowItem; + private WorkflowItem workflowItem; @Column(name = "finished") private boolean finished = false; @@ -71,11 +72,11 @@ public class InProgressUser implements ReloadableEntity { return this.ePerson; } - public void setWorkflowItem(XmlWorkflowItem workflowItem) { + public void setWorkflowItem(WorkflowItem workflowItem) { this.workflowItem = workflowItem; } - public XmlWorkflowItem getWorkflowItem() { + public WorkflowItem getWorkflowItem() { return this.workflowItem; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUserServiceImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUserServiceImpl.java index a2b5e718eb..b88fd5d4f3 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUserServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUserServiceImpl.java @@ -15,6 +15,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.InProgressUserDAO; import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService; import org.springframework.beans.factory.annotation.Autowired; @@ -36,7 +37,7 @@ public class InProgressUserServiceImpl implements InProgressUserService { } @Override - public InProgressUser findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) + public InProgressUser findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) throws SQLException { return inProgressUserDAO.findByWorkflowItemAndEPerson(context, workflowItem, ePerson); } @@ -47,17 +48,17 @@ public class InProgressUserServiceImpl implements InProgressUserService { } @Override - public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException { + public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException { return inProgressUserDAO.findByWorkflowItem(context, workflowItem); } @Override - public int getNumberOfInProgressUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException { + public int getNumberOfInProgressUsers(Context context, WorkflowItem workflowItem) throws SQLException { return inProgressUserDAO.countInProgressUsers(context, workflowItem); } @Override - public int getNumberOfFinishedUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException { + public int getNumberOfFinishedUsers(Context context, WorkflowItem workflowItem) throws SQLException { return inProgressUserDAO.countFinishedUsers(context, workflowItem); } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTask.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTask.java index 2a87de51cb..d7e1e360f1 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTask.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTask.java @@ -23,6 +23,7 @@ import org.dspace.core.Context; import org.dspace.core.ReloadableEntity; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; +import org.dspace.workflow.WorkflowItem; /** * Pool task representing the database representation of a pool task for a step and an eperson @@ -44,7 +45,7 @@ public class PoolTask implements ReloadableEntity { @OneToOne @JoinColumn(name = "workflowitem_id") - private XmlWorkflowItem workflowItem; + private WorkflowItem workflowItem; // @Column(name = "workflow_id") // @Lob @@ -106,11 +107,11 @@ public class PoolTask implements ReloadableEntity { return workflowId; } - public void setWorkflowItem(XmlWorkflowItem xmlWorkflowItem) { - this.workflowItem = xmlWorkflowItem; + public void setWorkflowItem(WorkflowItem workflowItem) { + this.workflowItem = workflowItem; } - public XmlWorkflowItem getWorkflowItem() { + public WorkflowItem getWorkflowItem() { return this.workflowItem; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTaskServiceImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTaskServiceImpl.java index f64f1b3942..b3fbdeee60 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTaskServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTaskServiceImpl.java @@ -21,6 +21,7 @@ import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; import org.dspace.eperson.service.GroupService; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.PoolTaskDAO; import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; @@ -67,7 +68,7 @@ public class PoolTaskServiceImpl implements PoolTaskService { for (Group group : groups) { List groupTasks = poolTaskDAO.findByGroup(context, group); for (PoolTask poolTask : groupTasks) { - XmlWorkflowItem workflowItem = poolTask.getWorkflowItem(); + WorkflowItem workflowItem = poolTask.getWorkflowItem(); if (inProgressUserService.findByWorkflowItemAndEPerson(context, workflowItem, ePerson) == null) { result.add(poolTask); } @@ -78,12 +79,12 @@ public class PoolTaskServiceImpl implements PoolTaskService { @Override - public List find(Context context, XmlWorkflowItem workflowItem) throws SQLException { + public List find(Context context, WorkflowItem workflowItem) throws SQLException { return poolTaskDAO.findByWorkflowItem(context, workflowItem); } @Override - public PoolTask findByWorkflowIdAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) + public PoolTask findByWorkflowIdAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) throws SQLException, AuthorizeException, IOException { PoolTask poolTask = poolTaskDAO.findByWorkflowItemAndEPerson(context, workflowItem, ePerson); @@ -113,9 +114,9 @@ public class PoolTaskServiceImpl implements PoolTaskService { } @Override - public void deleteByWorkflowItem(Context context, XmlWorkflowItem xmlWorkflowItem) + public void deleteByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException, AuthorizeException { - List tasks = find(context, xmlWorkflowItem); + List tasks = find(context, workflowItem); //Use an iterator to remove the tasks ! Iterator iterator = tasks.iterator(); while (iterator.hasNext()) { diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRole.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRole.java index 9a7e5a034c..e368709d82 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRole.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRole.java @@ -23,6 +23,7 @@ import org.dspace.core.Context; import org.dspace.core.ReloadableEntity; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; +import org.dspace.workflow.WorkflowItem; /** * Represents a workflow assignments database representation. @@ -51,7 +52,7 @@ public class WorkflowItemRole implements ReloadableEntity { @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "workflowitem_id") - private XmlWorkflowItem workflowItem; + private WorkflowItem workflowItem; @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "eperson_id") @@ -82,11 +83,11 @@ public class WorkflowItemRole implements ReloadableEntity { return this.roleId; } - public void setWorkflowItem(XmlWorkflowItem xmlWorkflowItem) { - this.workflowItem = xmlWorkflowItem; + public void setWorkflowItem(WorkflowItem workflowItem) { + this.workflowItem = workflowItem; } - public XmlWorkflowItem getWorkflowItem() { + public WorkflowItem getWorkflowItem() { return workflowItem; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRoleServiceImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRoleServiceImpl.java index 4204c7dcc3..b5872a5271 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRoleServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRoleServiceImpl.java @@ -16,6 +16,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.WorkflowItemRoleDAO; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; import org.springframework.beans.factory.annotation.Autowired; @@ -37,20 +38,20 @@ public class WorkflowItemRoleServiceImpl implements WorkflowItemRoleService { } @Override - public List find(Context context, XmlWorkflowItem workflowItem, String role) throws SQLException { + public List find(Context context, WorkflowItem workflowItem, String role) throws SQLException { return workflowItemRoleDAO.findByWorkflowItemAndRole(context, workflowItem, role); } @Override - public List findByWorkflowItem(Context context, XmlWorkflowItem xmlWorkflowItem) + public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException { - return workflowItemRoleDAO.findByWorkflowItem(context, xmlWorkflowItem); + return workflowItemRoleDAO.findByWorkflowItem(context, workflowItem); } @Override - public void deleteForWorkflowItem(Context context, XmlWorkflowItem xmlWorkflowItem) + public void deleteForWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException, AuthorizeException { - Iterator workflowItemRoles = findByWorkflowItem(context, xmlWorkflowItem).iterator(); + Iterator workflowItemRoles = findByWorkflowItem(context, workflowItem).iterator(); while (workflowItemRoles.hasNext()) { WorkflowItemRole workflowItemRole = workflowItemRoles.next(); workflowItemRoles.remove(); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItem.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItem.java deleted file mode 100644 index 4108500707..0000000000 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItem.java +++ /dev/null @@ -1,141 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.xmlworkflow.storedcomponents; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToOne; -import javax.persistence.SequenceGenerator; -import javax.persistence.Table; - -import org.dspace.content.Collection; -import org.dspace.content.Item; -import org.dspace.core.Context; -import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; - -/** - * Class representing an item going through the workflow process in DSpace - * - * @author Bram De Schouwer (bram.deschouwer at dot com) - * @author Kevin Van de Velde (kevin at atmire dot com) - * @author Ben Bosman (ben at atmire dot com) - * @author Mark Diggory (markd at atmire dot com) - */ -@Entity -@Table(name = "cwf_workflowitem") -public class XmlWorkflowItem implements WorkflowItem { - - @Id - @Column(name = "workflowitem_id") - @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "cwf_workflowitem_seq") - @SequenceGenerator(name = "cwf_workflowitem_seq", sequenceName = "cwf_workflowitem_seq", allocationSize = 1) - private Integer id; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "collection_id") - private Collection collection; - - @OneToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "item_id", unique = true) - private Item item; - - @Column(name = "multiple_titles") - private boolean multipleTitles = false; - - @Column(name = "published_before") - private boolean publishedBefore = false; - - @Column(name = "multiple_files") - private boolean multipleFiles = false; - - /** - * Protected constructor, create object using: - * {@link org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService#create(Context, Item, Collection)} - */ - protected XmlWorkflowItem() { - - } - - /** - * Get the internal ID of this workflow item - * - * @return the internal identifier - */ - @Override - public Integer getID() { - return id; - } - - - @Override - public Collection getCollection() { - return this.collection; - } - - public void setCollection(Collection collection) { - this.collection = collection; - } - - @Override - public Item getItem() { - return item; - } - - public void setItem(Item item) { - this.item = item; - } - - @Override - public EPerson getSubmitter() { - return item.getSubmitter(); - } - - @Override - public boolean hasMultipleFiles() { - return multipleFiles; - } - - @Override - public void setMultipleFiles(boolean b) { - this.multipleFiles = b; - } - - @Override - public boolean hasMultipleTitles() { - return this.multipleTitles; - } - - @Override - public void setMultipleTitles(boolean b) { - this.multipleTitles = b; - } - - @Override - public boolean isPublishedBefore() { - return this.publishedBefore; - } - - @Override - public void setPublishedBefore(boolean b) { - this.publishedBefore = b; - } - - @Override - public int getState() { - // FIXME not used by the xml workflow, should be removed when the basic workflow is removed and the interfaces - // simplified - return 0; - } -} diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/ClaimedTaskDAO.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/ClaimedTaskDAO.java index 7f97e14006..d7663391fa 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/ClaimedTaskDAO.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/ClaimedTaskDAO.java @@ -13,8 +13,8 @@ import java.util.List; import org.dspace.core.Context; import org.dspace.core.GenericDAO; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Database Access Object interface class for the ClaimedTask object. @@ -26,21 +26,21 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; */ public interface ClaimedTaskDAO extends GenericDAO { - public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException; + public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException; - public ClaimedTask findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) + public ClaimedTask findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) throws SQLException; public List findByEperson(Context context, EPerson ePerson) throws SQLException; - public List findByWorkflowItemAndStepId(Context context, XmlWorkflowItem workflowItem, String stepID) + public List findByWorkflowItemAndStepId(Context context, WorkflowItem workflowItem, String stepID) throws SQLException; public ClaimedTask findByEPersonAndWorkflowItemAndStepIdAndActionId(Context context, EPerson ePerson, - XmlWorkflowItem workflowItem, String stepID, + WorkflowItem workflowItem, String stepID, String actionID) throws SQLException; - public List findByWorkflowItemAndStepIdAndActionId(Context c, XmlWorkflowItem workflowItem, + public List findByWorkflowItemAndStepIdAndActionId(Context c, WorkflowItem workflowItem, String stepID, String actionID) throws SQLException; public List findByStep(Context context, String stepID) throws SQLException; diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/InProgressUserDAO.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/InProgressUserDAO.java index b08d5afc21..ceee789c4b 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/InProgressUserDAO.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/InProgressUserDAO.java @@ -13,8 +13,8 @@ import java.util.List; import org.dspace.core.Context; import org.dspace.core.GenericDAO; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.InProgressUser; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Database Access Object interface class for the InProgressUser object. @@ -26,14 +26,14 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; */ public interface InProgressUserDAO extends GenericDAO { - public InProgressUser findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) + public InProgressUser findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) throws SQLException; public List findByEperson(Context context, EPerson ePerson) throws SQLException; - public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException; + public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException; - public int countInProgressUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException; + public int countInProgressUsers(Context context, WorkflowItem workflowItem) throws SQLException; - public int countFinishedUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException; + public int countFinishedUsers(Context context, WorkflowItem workflowItem) throws SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/PoolTaskDAO.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/PoolTaskDAO.java index 55aed546d9..ae21f13552 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/PoolTaskDAO.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/PoolTaskDAO.java @@ -14,8 +14,8 @@ import org.dspace.core.Context; import org.dspace.core.GenericDAO; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.PoolTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Database Access Object interface class for the PoolTask object. @@ -31,11 +31,11 @@ public interface PoolTaskDAO extends GenericDAO { public List findByGroup(Context context, Group group) throws SQLException; - public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException; + public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException; - public PoolTask findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) + public PoolTask findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) throws SQLException; - public PoolTask findByWorkflowItemAndGroup(Context context, Group group, XmlWorkflowItem workflowItem) + public PoolTask findByWorkflowItemAndGroup(Context context, Group group, WorkflowItem workflowItem) throws SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/XmlWorkflowItemDAO.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/WorkflowItemDAO.java similarity index 72% rename from dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/XmlWorkflowItemDAO.java rename to dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/WorkflowItemDAO.java index d0d11886aa..2a414fe14a 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/XmlWorkflowItemDAO.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/WorkflowItemDAO.java @@ -15,17 +15,17 @@ import org.dspace.content.Item; import org.dspace.core.Context; import org.dspace.core.GenericDAO; import org.dspace.eperson.EPerson; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.workflow.WorkflowItem; /** - * Database Access Object interface class for the XmlWorkflowItem object. - * The implementation of this class is responsible for all database calls for the XmlWorkflowItem object and is + * Database Access Object interface class for the WorkflowItem object. + * The implementation of this class is responsible for all database calls for the WorkflowItem object and is * autowired by spring * This class should only be accessed from a single service and should never be exposed outside of the API * * @author kevinvandevelde at atmire.com */ -public interface XmlWorkflowItemDAO extends GenericDAO { +public interface WorkflowItemDAO extends GenericDAO { /** * Find all the workflow items in a specific collection using the pagination parameters (offset, limit) @@ -41,18 +41,18 @@ public interface XmlWorkflowItemDAO extends GenericDAO { * @return all the workflow items respecting the parameters conditions * @throws SQLException */ - public List findAllInCollection(Context context, Integer offset, Integer limit, - Collection collection) throws SQLException; + public List findAllInCollection(Context context, Integer offset, Integer limit, + Collection collection) throws SQLException; public int countAll(Context context) throws SQLException; public int countAllInCollection(Context context, Collection collection) throws SQLException; - public List findBySubmitter(Context context, EPerson ep) throws SQLException; + public List findBySubmitter(Context context, EPerson ep) throws SQLException; - public List findByCollection(Context context, Collection collection) throws SQLException; + public List findByCollection(Context context, Collection collection) throws SQLException; - public XmlWorkflowItem findByItem(Context context, Item item) throws SQLException; + public WorkflowItem findByItem(Context context, Item item) throws SQLException; /** * Return all the workflow items from a specific submitter respecting the pagination parameters @@ -67,7 +67,7 @@ public interface XmlWorkflowItemDAO extends GenericDAO { * the max number of records to return * @return */ - public List findBySubmitter(Context context, EPerson ep, Integer offset, Integer limit) + public List findBySubmitter(Context context, EPerson ep, Integer offset, Integer limit) throws SQLException; /** diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/WorkflowItemRoleDAO.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/WorkflowItemRoleDAO.java index 8ee9e4e4c0..36acda3473 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/WorkflowItemRoleDAO.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/WorkflowItemRoleDAO.java @@ -13,8 +13,8 @@ import java.util.List; import org.dspace.core.Context; import org.dspace.core.GenericDAO; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Database Access Object interface class for the WorkflowItemRole object. @@ -26,10 +26,10 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; */ public interface WorkflowItemRoleDAO extends GenericDAO { - public List findByWorkflowItemAndRole(Context context, XmlWorkflowItem workflowItem, String role) + public List findByWorkflowItemAndRole(Context context, WorkflowItem workflowItem, String role) throws SQLException; - public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException; + public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException; public List findByEPerson(Context context, EPerson ePerson) throws SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/ClaimedTaskDAOImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/ClaimedTaskDAOImpl.java index bb5a167237..a3063d4756 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/ClaimedTaskDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/ClaimedTaskDAOImpl.java @@ -16,9 +16,9 @@ import javax.persistence.criteria.Root; import org.dspace.core.AbstractHibernateDAO; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask_; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.ClaimedTaskDAO; /** @@ -34,7 +34,7 @@ public class ClaimedTaskDAOImpl extends AbstractHibernateDAO implem } @Override - public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException { + public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ClaimedTask.class); Root claimedTaskRoot = criteriaQuery.from(ClaimedTask.class); @@ -45,7 +45,7 @@ public class ClaimedTaskDAOImpl extends AbstractHibernateDAO implem } @Override - public ClaimedTask findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) + public ClaimedTask findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ClaimedTask.class); @@ -72,7 +72,7 @@ public class ClaimedTaskDAOImpl extends AbstractHibernateDAO implem } @Override - public List findByWorkflowItemAndStepId(Context context, XmlWorkflowItem workflowItem, String stepID) + public List findByWorkflowItemAndStepId(Context context, WorkflowItem workflowItem, String stepID) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ClaimedTask.class); @@ -88,7 +88,7 @@ public class ClaimedTaskDAOImpl extends AbstractHibernateDAO implem @Override public ClaimedTask findByEPersonAndWorkflowItemAndStepIdAndActionId(Context context, EPerson ePerson, - XmlWorkflowItem workflowItem, String stepID, + WorkflowItem workflowItem, String stepID, String actionID) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ClaimedTask.class); @@ -105,7 +105,7 @@ public class ClaimedTaskDAOImpl extends AbstractHibernateDAO implem } @Override - public List findByWorkflowItemAndStepIdAndActionId(Context context, XmlWorkflowItem workflowItem, + public List findByWorkflowItemAndStepIdAndActionId(Context context, WorkflowItem workflowItem, String stepID, String actionID) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/InProgressUserDAOImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/InProgressUserDAOImpl.java index cdba1600a8..1487864772 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/InProgressUserDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/InProgressUserDAOImpl.java @@ -16,9 +16,9 @@ import javax.persistence.criteria.Root; import org.dspace.core.AbstractHibernateDAO; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.InProgressUser; import org.dspace.xmlworkflow.storedcomponents.InProgressUser_; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.InProgressUserDAO; /** @@ -34,7 +34,7 @@ public class InProgressUserDAOImpl extends AbstractHibernateDAO } @Override - public InProgressUser findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) + public InProgressUser findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); @@ -61,7 +61,7 @@ public class InProgressUserDAOImpl extends AbstractHibernateDAO } @Override - public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException { + public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, InProgressUser.class); @@ -72,7 +72,7 @@ public class InProgressUserDAOImpl extends AbstractHibernateDAO } @Override - public int countInProgressUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException { + public int countInProgressUsers(Context context, WorkflowItem workflowItem) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Long.class); @@ -88,7 +88,7 @@ public class InProgressUserDAOImpl extends AbstractHibernateDAO } @Override - public int countFinishedUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException { + public int countFinishedUsers(Context context, WorkflowItem workflowItem) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Long.class); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/PoolTaskDAOImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/PoolTaskDAOImpl.java index b38041da39..2d4bfceb81 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/PoolTaskDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/PoolTaskDAOImpl.java @@ -17,9 +17,9 @@ import org.dspace.core.AbstractHibernateDAO; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.PoolTask; import org.dspace.xmlworkflow.storedcomponents.PoolTask_; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.PoolTaskDAO; /** @@ -56,7 +56,7 @@ public class PoolTaskDAOImpl extends AbstractHibernateDAO implements P } @Override - public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException { + public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, PoolTask.class); Root poolTaskRoot = criteriaQuery.from(PoolTask.class); @@ -66,7 +66,7 @@ public class PoolTaskDAOImpl extends AbstractHibernateDAO implements P } @Override - public PoolTask findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) + public PoolTask findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, PoolTask.class); @@ -81,7 +81,7 @@ public class PoolTaskDAOImpl extends AbstractHibernateDAO implements P } @Override - public PoolTask findByWorkflowItemAndGroup(Context context, Group group, XmlWorkflowItem workflowItem) + public PoolTask findByWorkflowItemAndGroup(Context context, Group group, WorkflowItem workflowItem) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, PoolTask.class); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemDAOImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemDAOImpl.java new file mode 100644 index 0000000000..53827a95f0 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemDAOImpl.java @@ -0,0 +1,137 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.xmlworkflow.storedcomponents.dao.impl; + +import java.sql.SQLException; +import java.util.List; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Join; +import javax.persistence.criteria.Root; + +import org.dspace.content.Collection; +import org.dspace.content.Item; +import org.dspace.content.Item_; +import org.dspace.core.AbstractHibernateDAO; +import org.dspace.core.Context; +import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowItem_; +import org.dspace.xmlworkflow.storedcomponents.dao.WorkflowItemDAO; + +/** + * Hibernate implementation of the Database Access Object interface class for the WorkflowItem object. + * This class is responsible for all database calls for the WorkflowItem object and is autowired by spring + * This class should never be accessed directly. + * + * @author kevinvandevelde at atmire.com + */ +public class WorkflowItemDAOImpl extends AbstractHibernateDAO implements WorkflowItemDAO { + + protected WorkflowItemDAOImpl() { + super(); + } + + @Override + public List findAllInCollection(Context context, Integer offset, + Integer limit, + Collection collection) throws SQLException { + CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); + CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, WorkflowItem.class); + Root workflowItemRoot = criteriaQuery.from(WorkflowItem.class); + criteriaQuery.select(workflowItemRoot); + if (collection != null) { + criteriaQuery.where(criteriaBuilder.equal(workflowItemRoot.get(WorkflowItem_.collection), + collection)); + } + if (offset == null) { + offset = -1; + } + if (limit == null) { + limit = -1; + } + criteriaQuery.orderBy(criteriaBuilder.asc(workflowItemRoot.get(WorkflowItem_.id))); + return list(context, criteriaQuery, false, WorkflowItem.class, limit, offset); + } + + @Override + public int countAll(Context context) throws SQLException { + return countAllInCollection(context, null); + } + + @Override + public int countAllInCollection(Context context, Collection collection) throws SQLException { + + + CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); + CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Long.class); + + Root workflowItemRoot = criteriaQuery.from(WorkflowItem.class); + if (collection != null) { + criteriaQuery.where(criteriaBuilder.equal(workflowItemRoot.get(WorkflowItem_.collection), + collection)); + } + return count(context, criteriaQuery, criteriaBuilder, workflowItemRoot); + } + + @Override + public List findBySubmitter(Context context, EPerson ep) throws SQLException { + return findBySubmitter(context, ep, null, null); + } + + @Override + public List findBySubmitter(Context context, EPerson ep, Integer offset, Integer limit) + throws SQLException { + if (offset == null) { + offset = -1; + } + if (limit == null) { + limit = -1; + } + + CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); + CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, WorkflowItem.class); + Root workflowItemRoot = criteriaQuery.from(WorkflowItem.class); + Join join = workflowItemRoot.join("item"); + criteriaQuery.select(workflowItemRoot); + criteriaQuery.where(criteriaBuilder.equal(join.get(Item_.submitter), ep)); + criteriaQuery.orderBy(criteriaBuilder.asc(workflowItemRoot.get(WorkflowItem_.id))); + return list(context, criteriaQuery, false, WorkflowItem.class, limit, offset); + } + + @Override + public int countBySubmitter(Context context, EPerson ep) throws SQLException { + CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); + CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Long.class); + Root workflowItemRoot = criteriaQuery.from(WorkflowItem.class); + Join join = workflowItemRoot.join("item"); + criteriaQuery.where(criteriaBuilder.equal(join.get(Item_.submitter), ep)); + return count(context, criteriaQuery, criteriaBuilder, workflowItemRoot); + } + + @Override + public List findByCollection(Context context, Collection collection) throws SQLException { + CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); + CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, WorkflowItem.class); + Root workflowItemRoot = criteriaQuery.from(WorkflowItem.class); + criteriaQuery.select(workflowItemRoot); + criteriaQuery.where(criteriaBuilder.equal(workflowItemRoot.get(WorkflowItem_.collection), collection)); + criteriaQuery.orderBy(criteriaBuilder.asc(workflowItemRoot.get(WorkflowItem_.id))); + return list(context, criteriaQuery, false, WorkflowItem.class, -1, -1); + } + + @Override + public WorkflowItem findByItem(Context context, Item item) throws SQLException { + CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); + CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, WorkflowItem.class); + Root workflowItemRoot = criteriaQuery.from(WorkflowItem.class); + criteriaQuery.select(workflowItemRoot); + criteriaQuery.where(criteriaBuilder.equal(workflowItemRoot.get(WorkflowItem_.item), item)); + return uniqueResult(context, criteriaQuery, false, WorkflowItem.class, -1, -1); + } +} diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemRoleDAOImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemRoleDAOImpl.java index fdc2413b5f..ca7b2c78ad 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemRoleDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemRoleDAOImpl.java @@ -16,9 +16,9 @@ import javax.persistence.criteria.Root; import org.dspace.core.AbstractHibernateDAO; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole_; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.WorkflowItemRoleDAO; /** @@ -36,7 +36,7 @@ public class WorkflowItemRoleDAOImpl extends AbstractHibernateDAO findByWorkflowItemAndRole(Context context, - XmlWorkflowItem workflowItem, + WorkflowItem workflowItem, String role) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, WorkflowItemRole.class); @@ -55,7 +55,7 @@ public class WorkflowItemRoleDAOImpl extends AbstractHibernateDAO findByWorkflowItem(Context context, - XmlWorkflowItem workflowItem) throws SQLException { + WorkflowItem workflowItem) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, WorkflowItemRole.class); Root workflowItemRoleRoot = criteriaQuery.from(WorkflowItemRole.class); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/XmlWorkflowItemDAOImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/XmlWorkflowItemDAOImpl.java deleted file mode 100644 index 51728af7a4..0000000000 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/XmlWorkflowItemDAOImpl.java +++ /dev/null @@ -1,137 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.xmlworkflow.storedcomponents.dao.impl; - -import java.sql.SQLException; -import java.util.List; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Join; -import javax.persistence.criteria.Root; - -import org.dspace.content.Collection; -import org.dspace.content.Item; -import org.dspace.content.Item_; -import org.dspace.core.AbstractHibernateDAO; -import org.dspace.core.Context; -import org.dspace.eperson.EPerson; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem_; -import org.dspace.xmlworkflow.storedcomponents.dao.XmlWorkflowItemDAO; - -/** - * Hibernate implementation of the Database Access Object interface class for the XmlWorkflowItem object. - * This class is responsible for all database calls for the XmlWorkflowItem object and is autowired by spring - * This class should never be accessed directly. - * - * @author kevinvandevelde at atmire.com - */ -public class XmlWorkflowItemDAOImpl extends AbstractHibernateDAO implements XmlWorkflowItemDAO { - - protected XmlWorkflowItemDAOImpl() { - super(); - } - - @Override - public List findAllInCollection(Context context, Integer offset, - Integer limit, - Collection collection) throws SQLException { - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, XmlWorkflowItem.class); - Root xmlWorkflowItemRoot = criteriaQuery.from(XmlWorkflowItem.class); - criteriaQuery.select(xmlWorkflowItemRoot); - if (collection != null) { - criteriaQuery.where(criteriaBuilder.equal(xmlWorkflowItemRoot.get(XmlWorkflowItem_.collection), - collection)); - } - if (offset == null) { - offset = -1; - } - if (limit == null) { - limit = -1; - } - criteriaQuery.orderBy(criteriaBuilder.asc(xmlWorkflowItemRoot.get(XmlWorkflowItem_.id))); - return list(context, criteriaQuery, false, XmlWorkflowItem.class, limit, offset); - } - - @Override - public int countAll(Context context) throws SQLException { - return countAllInCollection(context, null); - } - - @Override - public int countAllInCollection(Context context, Collection collection) throws SQLException { - - - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Long.class); - - Root xmlWorkflowItemRoot = criteriaQuery.from(XmlWorkflowItem.class); - if (collection != null) { - criteriaQuery.where(criteriaBuilder.equal(xmlWorkflowItemRoot.get(XmlWorkflowItem_.collection), - collection)); - } - return count(context, criteriaQuery, criteriaBuilder, xmlWorkflowItemRoot); - } - - @Override - public List findBySubmitter(Context context, EPerson ep) throws SQLException { - return findBySubmitter(context, ep, null, null); - } - - @Override - public List findBySubmitter(Context context, EPerson ep, Integer offset, Integer limit) - throws SQLException { - if (offset == null) { - offset = -1; - } - if (limit == null) { - limit = -1; - } - - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, XmlWorkflowItem.class); - Root xmlWorkflowItemRoot = criteriaQuery.from(XmlWorkflowItem.class); - Join join = xmlWorkflowItemRoot.join("item"); - criteriaQuery.select(xmlWorkflowItemRoot); - criteriaQuery.where(criteriaBuilder.equal(join.get(Item_.submitter), ep)); - criteriaQuery.orderBy(criteriaBuilder.asc(xmlWorkflowItemRoot.get(XmlWorkflowItem_.id))); - return list(context, criteriaQuery, false, XmlWorkflowItem.class, limit, offset); - } - - @Override - public int countBySubmitter(Context context, EPerson ep) throws SQLException { - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Long.class); - Root xmlWorkflowItemRoot = criteriaQuery.from(XmlWorkflowItem.class); - Join join = xmlWorkflowItemRoot.join("item"); - criteriaQuery.where(criteriaBuilder.equal(join.get(Item_.submitter), ep)); - return count(context, criteriaQuery, criteriaBuilder, xmlWorkflowItemRoot); - } - - @Override - public List findByCollection(Context context, Collection collection) throws SQLException { - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, XmlWorkflowItem.class); - Root xmlWorkflowItemRoot = criteriaQuery.from(XmlWorkflowItem.class); - criteriaQuery.select(xmlWorkflowItemRoot); - criteriaQuery.where(criteriaBuilder.equal(xmlWorkflowItemRoot.get(XmlWorkflowItem_.collection), collection)); - criteriaQuery.orderBy(criteriaBuilder.asc(xmlWorkflowItemRoot.get(XmlWorkflowItem_.id))); - return list(context, criteriaQuery, false, XmlWorkflowItem.class, -1, -1); - } - - @Override - public XmlWorkflowItem findByItem(Context context, Item item) throws SQLException { - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, XmlWorkflowItem.class); - Root xmlWorkflowItemRoot = criteriaQuery.from(XmlWorkflowItem.class); - criteriaQuery.select(xmlWorkflowItemRoot); - criteriaQuery.where(criteriaBuilder.equal(xmlWorkflowItemRoot.get(XmlWorkflowItem_.item), item)); - return uniqueResult(context, criteriaQuery, false, XmlWorkflowItem.class, -1, -1); - } -} diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/ClaimedTaskService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/ClaimedTaskService.java index 667ca898b5..052d28d037 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/ClaimedTaskService.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/ClaimedTaskService.java @@ -14,8 +14,8 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.service.DSpaceCRUDService; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Service interface class for the ClaimedTask object. @@ -26,26 +26,26 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; */ public interface ClaimedTaskService extends DSpaceCRUDService { - public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException; + public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException; - public ClaimedTask findByWorkflowIdAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) + public ClaimedTask findByWorkflowIdAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) throws SQLException; public List findByEperson(Context context, EPerson ePerson) throws SQLException; - public List find(Context context, XmlWorkflowItem workflowItem, String stepID) throws SQLException; + public List find(Context context, WorkflowItem workflowItem, String stepID) throws SQLException; - public ClaimedTask find(Context context, EPerson ePerson, XmlWorkflowItem workflowItem, String stepID, + public ClaimedTask find(Context context, EPerson ePerson, WorkflowItem workflowItem, String stepID, String actionID) throws SQLException; - public List find(Context context, XmlWorkflowItem workflowItem, String stepID, String actionID) + public List find(Context context, WorkflowItem workflowItem, String stepID, String actionID) throws SQLException; - public List find(Context context, XmlWorkflowItem workflowItem) throws SQLException; + public List find(Context context, WorkflowItem workflowItem) throws SQLException; public List findAllInStep(Context context, String stepID) throws SQLException; - public void deleteByWorkflowItem(Context context, XmlWorkflowItem workflowItem) + public void deleteByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException, AuthorizeException; List findAll(Context context) throws SQLException; diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/InProgressUserService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/InProgressUserService.java index d90d73e7c9..fa2631bbf0 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/InProgressUserService.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/InProgressUserService.java @@ -13,8 +13,8 @@ import java.util.List; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.service.DSpaceCRUDService; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.InProgressUser; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Service interface class for the InProgressUser object. @@ -24,14 +24,14 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; * @author kevinvandevelde at atmire.com */ public interface InProgressUserService extends DSpaceCRUDService { - public InProgressUser findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) + public InProgressUser findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) throws SQLException; public List findByEperson(Context context, EPerson ePerson) throws SQLException; - public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException; + public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException; - public int getNumberOfInProgressUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException; + public int getNumberOfInProgressUsers(Context context, WorkflowItem workflowItem) throws SQLException; - public int getNumberOfFinishedUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException; + public int getNumberOfFinishedUsers(Context context, WorkflowItem workflowItem) throws SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/PoolTaskService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/PoolTaskService.java index 7f5ed5e6a0..08e0a342b4 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/PoolTaskService.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/PoolTaskService.java @@ -16,8 +16,8 @@ import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; import org.dspace.service.DSpaceCRUDService; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.PoolTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Service interface class for the PoolTask object. @@ -33,12 +33,12 @@ public interface PoolTaskService extends DSpaceCRUDService { public List findByEperson(Context context, EPerson ePerson) throws SQLException, AuthorizeException, IOException; - public List find(Context context, XmlWorkflowItem workflowItem) throws SQLException; + public List find(Context context, WorkflowItem workflowItem) throws SQLException; - public PoolTask findByWorkflowIdAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) + public PoolTask findByWorkflowIdAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) throws SQLException, AuthorizeException, IOException; - public void deleteByWorkflowItem(Context context, XmlWorkflowItem xmlWorkflowItem) + public void deleteByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException, AuthorizeException; public void deleteByEperson(Context context, EPerson ePerson) throws SQLException, AuthorizeException, IOException; diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/WorkflowItemRoleService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/WorkflowItemRoleService.java index 9f909231f1..33b2f6a007 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/WorkflowItemRoleService.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/WorkflowItemRoleService.java @@ -14,8 +14,8 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.service.DSpaceCRUDService; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Service interface class for the WorkflowItemRole object. @@ -26,12 +26,12 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; */ public interface WorkflowItemRoleService extends DSpaceCRUDService { - public List find(Context context, XmlWorkflowItem workflowItem, String role) throws SQLException; + public List find(Context context, WorkflowItem workflowItem, String role) throws SQLException; - public List findByWorkflowItem(Context context, XmlWorkflowItem xmlWorkflowItem) + public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException; - public void deleteForWorkflowItem(Context context, XmlWorkflowItem wfi) throws SQLException, AuthorizeException; + public void deleteForWorkflowItem(Context context, WorkflowItem wfi) throws SQLException, AuthorizeException; public void deleteByEPerson(Context context, EPerson ePerson) throws SQLException, AuthorizeException; diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/XmlWorkflowItemService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/XmlWorkflowItemService.java deleted file mode 100644 index 76b1fa0817..0000000000 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/XmlWorkflowItemService.java +++ /dev/null @@ -1,100 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.xmlworkflow.storedcomponents.service; - -import java.sql.SQLException; -import java.util.List; - -import org.dspace.content.Collection; -import org.dspace.core.Context; -import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; - -/** - * Service interface class for the XmlWorkflowItem object. - * The implementation of this class is responsible for all business logic calls for the XmlWorkflowItem object and is - * autowired by spring - * - * @author kevinvandevelde at atmire.com - */ -public interface XmlWorkflowItemService extends WorkflowItemService { - - /** - * return all workflowitems for a certain page - * - * @param context The relevant DSpace Context. - * @param page paging: page number - * @param pagesize paging: items per page - * @return WorkflowItem list of all the workflow items in system - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - public List findAll(Context context, Integer page, Integer pagesize) throws SQLException; - - /** - * return all workflowitems for a certain page with a certain collection - * - * @param context The relevant DSpace Context. - * @param page paging: page number - * @param pagesize paging: items per page - * @param collection restrict to this collection - * @return WorkflowItem list of all the workflow items in system - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - public List findAllInCollection(Context context, Integer page, Integer pagesize, - Collection collection) throws SQLException; - - /** - * return how many workflow items appear in the database - * - * @param context The relevant DSpace Context. - * @return the number of workflow items - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - public int countAll(Context context) throws SQLException; - - /** - * return how many workflow items that appear in the collection - * - * @param context The relevant DSpace Context. - * @param collection restrict to this collection - * @return the number of workflow items - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - public int countAllInCollection(Context context, Collection collection) throws SQLException; - - /** - * Return all the workflow items from a specific submitter respecting the pagination parameters - * - * @param context - * The relevant DSpace Context. - * @param ep - * the eperson that has submitted the item - * @param pageNumber - * paging: page number - * @param pageSize - * paging: items per page - * @return - * @throws SQLException - */ - public List findBySubmitter(Context context, EPerson ep, Integer pageNumber, Integer pageSize) - throws SQLException; - - /** - * Count the number of workflow items from a specific submitter - * - * @param context - * The relevant DSpace Context. - * @param ep - * the eperson that has submitted the item - * @return - * @throws SQLException - */ - public int countBySubmitter(Context context, EPerson ep) throws SQLException; - -} diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.01.22__Remove_basic_workflow.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.01.22__Remove_basic_workflow.sql new file mode 100644 index 0000000000..f71173abe6 --- /dev/null +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.01.22__Remove_basic_workflow.sql @@ -0,0 +1,17 @@ +-- +-- The contents of this file are subject to the license and copyright +-- detailed in the LICENSE and NOTICE files at the root of the source +-- tree and available online at +-- +-- http://www.dspace.org/license/ +-- + +----------------------------------------------------------------------------------- +-- Drop the 'workflowitem' and 'tasklistitem' tables +----------------------------------------------------------------------------------- + +DROP TABLE workflowitem CASCADE CONSTRAINTS; +DROP TABLE tasklistitem CASCADE CONSTRAINTS; + +DROP SEQUENCE workflowitem_seq; +DROP SEQUENCE tasklistitem_seq; \ No newline at end of file diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.01.22__Remove_basic_workflow.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.01.22__Remove_basic_workflow.sql new file mode 100644 index 0000000000..f71173abe6 --- /dev/null +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.01.22__Remove_basic_workflow.sql @@ -0,0 +1,17 @@ +-- +-- The contents of this file are subject to the license and copyright +-- detailed in the LICENSE and NOTICE files at the root of the source +-- tree and available online at +-- +-- http://www.dspace.org/license/ +-- + +----------------------------------------------------------------------------------- +-- Drop the 'workflowitem' and 'tasklistitem' tables +----------------------------------------------------------------------------------- + +DROP TABLE workflowitem CASCADE CONSTRAINTS; +DROP TABLE tasklistitem CASCADE CONSTRAINTS; + +DROP SEQUENCE workflowitem_seq; +DROP SEQUENCE tasklistitem_seq; \ No newline at end of file diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.01.22__Remove_basic_workflow.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.01.22__Remove_basic_workflow.sql new file mode 100644 index 0000000000..50a09706e2 --- /dev/null +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.01.22__Remove_basic_workflow.sql @@ -0,0 +1,17 @@ +-- +-- The contents of this file are subject to the license and copyright +-- detailed in the LICENSE and NOTICE files at the root of the source +-- tree and available online at +-- +-- http://www.dspace.org/license/ +-- + +----------------------------------------------------------------------------------- +-- Drop the 'workflowitem' and 'tasklistitem' tables +----------------------------------------------------------------------------------- + +DROP TABLE workflowitem CASCADE; +DROP TABLE tasklistitem CASCADE; + +DROP SEQUENCE workflowitem_seq; +DROP SEQUENCE tasklistitem_seq; \ No newline at end of file diff --git a/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java b/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java index 31c0298824..ab6da04605 100644 --- a/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java @@ -44,13 +44,13 @@ import org.dspace.scripts.service.ProcessService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.versioning.factory.VersionServiceFactory; import org.dspace.versioning.service.VersionHistoryService; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; -import org.dspace.xmlworkflow.service.XmlWorkflowService; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.WorkflowService; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; /** * Abstract builder class that holds references to all available services @@ -66,8 +66,8 @@ public abstract class AbstractBuilder { static ItemService itemService; static InstallItemService installItemService; static WorkspaceItemService workspaceItemService; - static XmlWorkflowItemService workflowItemService; - static XmlWorkflowService workflowService; + static WorkflowItemService workflowItemService; + static WorkflowService workflowService; static EPersonService ePersonService; static GroupService groupService; static BundleService bundleService; @@ -115,8 +115,8 @@ public abstract class AbstractBuilder { itemService = ContentServiceFactory.getInstance().getItemService(); installItemService = ContentServiceFactory.getInstance().getInstallItemService(); workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); - workflowItemService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService(); - workflowService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); + workflowItemService = WorkflowServiceFactory.getInstance().getWorkflowItemService(); + workflowService = WorkflowServiceFactory.getInstance().getWorkflowService(); ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); groupService = EPersonServiceFactory.getInstance().getGroupService(); bundleService = ContentServiceFactory.getInstance().getBundleService(); @@ -138,10 +138,10 @@ public abstract class AbstractBuilder { processService = ScriptServiceFactory.getInstance().getProcessService(); // Temporarily disabled - claimedTaskService = XmlWorkflowServiceFactory.getInstance().getClaimedTaskService(); - inProgressUserService = XmlWorkflowServiceFactory.getInstance().getInProgressUserService(); - poolTaskService = XmlWorkflowServiceFactory.getInstance().getPoolTaskService(); - workflowItemRoleService = XmlWorkflowServiceFactory.getInstance().getWorkflowItemRoleService(); + claimedTaskService = WorkflowServiceFactory.getInstance().getClaimedTaskService(); + inProgressUserService = WorkflowServiceFactory.getInstance().getInProgressUserService(); + poolTaskService = WorkflowServiceFactory.getInstance().getPoolTaskService(); + workflowItemRoleService = WorkflowServiceFactory.getInstance().getWorkflowItemRoleService(); } diff --git a/dspace-api/src/test/java/org/dspace/builder/ClaimedTaskBuilder.java b/dspace-api/src/test/java/org/dspace/builder/ClaimedTaskBuilder.java index 338739285f..fa66d78b8a 100644 --- a/dspace-api/src/test/java/org/dspace/builder/ClaimedTaskBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/ClaimedTaskBuilder.java @@ -20,13 +20,13 @@ import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.event.Event; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.PoolTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; /** @@ -37,7 +37,7 @@ public class ClaimedTaskBuilder extends AbstractBuilder private WorkspaceItem workspaceItem; - private XmlWorkflowItem workflowItem; + private WorkflowItem workflowItem; private PoolTask poolTask; diff --git a/dspace-api/src/test/java/org/dspace/builder/WorkflowItemBuilder.java b/dspace-api/src/test/java/org/dspace/builder/WorkflowItemBuilder.java index bd76e9e613..cf772ffd7c 100644 --- a/dspace-api/src/test/java/org/dspace/builder/WorkflowItemBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/WorkflowItemBuilder.java @@ -22,21 +22,21 @@ import org.dspace.content.WorkspaceItem; import org.dspace.core.Context; import org.dspace.discovery.SearchServiceException; import org.dspace.eperson.EPerson; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowItemService; /** * Builder to construct WorkflowItem objects * **/ -public class WorkflowItemBuilder extends AbstractBuilder { +public class WorkflowItemBuilder extends AbstractBuilder { /** Keep a reference to the underlying Item for cleanup **/ private Item item; private WorkspaceItem workspaceItem; - private XmlWorkflowItem workflowItem; + private WorkflowItem workflowItem; protected WorkflowItemBuilder(Context context) { super(context); @@ -72,7 +72,7 @@ public class WorkflowItemBuilder extends AbstractBuilder roleGroups = new HashMap<>(); - protected HashMap roleEPersons = new HashMap<>(); - - public BasicWorkflowAuthorizationRolesIT() { - owningCommunity = null; - collection = null; - item = null; - wsi = null; - wfi = null; - mgroup = null; - member = null; - roleGroups.clear(); - roleEPersons.clear(); - } - - /** - * This method will be run before every test as per @Before. It will - * initialize resources required for the tests. - * - * Other methods can be annotated with @Before here or in subclasses - * but no execution order is guaranteed - */ - @Before - @Override - public void init() { - super.init(); - - try { - //we have to create a new community in the database - configurationService.setProperty("workflow.notify.returned.tasks", false); - context.turnOffAuthorisationSystem(); - - long date = new Date().getTime(); - this.owningCommunity = communityService.create(null, context); - this.collection = collectionService.create(context, owningCommunity); - this.member = ePersonService.create(context); - member.setEmail(String.format("wf-member-%d@example.org", date)); - member.setFirstName(context, "Member"); - ePersonService.update(context, member); - this.mgroup = groupService.create(context); - groupService.addMember(context, mgroup, member); - groupService.setName(mgroup, String.format("Member Group %d", date)); - groupService.update(context, mgroup); - for (ROLE role : ROLE.values()) { - EPerson person = ePersonService.create(context); - person.setFirstName(context, String.format("%d", date)); - person.setLastName(context, String.format("Role %s", role.toString())); - person.setEmail(String.format("basicwf-test-%s-%d@example.org", role.toString(), date)); - ePersonService.update(context, person); - roleEPersons.put(role, person); - Group pgroup = groupService.create(context); - roleGroups.put(role, pgroup); - groupService.setName(pgroup, String.format("Group %s %d", role.toString(), date)); - groupService.addMember(context, pgroup, person); - groupService.update(context, pgroup); - log.info(String.format("Create ROLE %s GROUP %s PERSON %s", role.toString(), pgroup.getName(), - person.getFullName())); - } - } catch (AuthorizeException ex) { - log.error("Authorization Error in init", ex); - Assert.fail("Authorization Error in init: " + ex.getMessage()); - } catch (SQLException ex) { - log.error("SQL Error in init", ex); - Assert.fail("SQL Error in init: " + ex.getMessage()); - } finally { - // restore the authorization system as tests expect it to be in place - context.restoreAuthSystemState(); - } - } - - private void contextReload() { - try { - if (context.isValid()) { - context.commit(); - } else { - context.abort(); - } - context = new Context(); - owningCommunity = context.reloadEntity(owningCommunity); - collection = context.reloadEntity(collection); - member = context.reloadEntity(member); - mgroup = context.reloadEntity(mgroup); - if (item != null) { - UUID itemid = item.getID(); - context.uncacheEntity(item); - item = itemService.find(context, itemid); - } - wsi = context.reloadEntity(wsi); - if (wfi != null) { - int wfid = wfi.getID(); - context.uncacheEntity(wfi); - wfi = basicWorkflowItemService.find(context, wfid); - } - for (ROLE role : ROLE.values()) { - EPerson eperson = roleEPersons.get(role); - eperson = ePersonService.find(context, eperson.getID()); - Assert.assertNotNull(eperson); - roleEPersons.put(role, eperson); - roleGroups.put(role, context.reloadEntity(roleGroups.get(role))); - } - } catch (SQLException e) { - log.error("Error reloading context", e); - } - - } - - - /** - * This method will be run after every test as per @After. It will - * clean resources initialized by the @Before methods. - * - * Other methods can be annotated with @After here or in subclasses - * but no execution order is guaranteed - */ - @After - @Override - public void destroy() { - try { - super.destroy(); - } catch (Exception e) { - log.error("Error in super destroy", e); - } - } - - - /* - * Prepare a workspace item for subsequent tests - */ - private void setupItemAndStartWorkflow() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - context.setCurrentUser(roleEPersons.get(ROLE.SUB)); - wsi = workspaceItemService.create(context, collection, false); - item = wsi.getItem(); - Bundle bundle = bundleService.create(context, item, "ORIGINAL"); - File f = new File(AbstractDSpaceTest.testProps.get("test.bitstream").toString()); - bitstreamService.create(context, bundle, new FileInputStream(f)); - bundleService.update(context, bundle); - itemService.update(context, item); - workspaceItemService.update(context, wsi); - - wfi = basicWorkflowService.startWithoutNotify(context, wsi); - basicWorkflowItemService.update(context, wfi); - } - - private void setWorkflowGroup(Context context, int step, Group group) throws SQLException, AuthorizeException { - collection.setWorkflowGroup(context, step, group); - //collection.setWorkflowGroup(step, group); - } - - /* - * Model the permission set up for a collection with basic workflow. - * The last group to advance the item seems to need Add rights - * SUB has add rights. - */ - private void setStepPermissions(ROLE step1, ROLE step2, ROLE step3) throws SQLException, AuthorizeException { - authorizeService.addPolicy(context, collection, Constants.ADMIN, roleGroups.get(ROLE.ADMIN)); - Group last = null; - if (step1 != null) { - Group group = roleGroups.get(step1); - setWorkflowGroup(context, 1, group); - last = group; - } - if (step2 != null) { - Group group = roleGroups.get(step2); - setWorkflowGroup(context, 2, group); - last = group; - } - if (step3 != null) { - Group group = roleGroups.get(step3); - setWorkflowGroup(context, 3, group); - last = group; - } - - authorizeService.addPolicy(context, collection, Constants.ADD, last); - collectionService.update(context, collection); - } - - /** - * Test that appropriate claim and advance permissions are enforced for a workflow with only Step 1. - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithStep1AllRoles() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(ROLE.STEP1, null, null); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertEquals(collection.getWorkflowStep1(context), roleGroups.get(ROLE.STEP1)); - Assert.assertNull(collection.getWorkflowStep2(context)); - Assert.assertNull(collection.getWorkflowStep3(context)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP1); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - - attemptItemUnclaim(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP1); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP1); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that appropriate claim permissions are enforced for a workflow with only Step 1. - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithStep1AllRolesClaim() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(ROLE.STEP1, null, null); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertEquals(collection.getWorkflowStep1(context), roleGroups.get(ROLE.STEP1)); - Assert.assertNull(collection.getWorkflowStep2(context)); - Assert.assertNull(collection.getWorkflowStep3(context)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP1); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - - attemptItemUnclaim(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP1); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP1, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that expected transitions succeed for a workflow with only Step 1. - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithStep1ExpectedRoles() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(ROLE.STEP1, null, null); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertEquals(collection.getWorkflowStep1(context), roleGroups.get(ROLE.STEP1)); - Assert.assertNull(collection.getWorkflowStep2(context)); - Assert.assertNull(collection.getWorkflowStep3(context)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - - attemptItemUnclaim(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP1, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that appropriate claim and advance permissions are enforced for a submitter in a workflow with only Step 1. - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithStep1Submitter() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(ROLE.STEP1, null, null); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertEquals(collection.getWorkflowStep1(context), roleGroups.get(ROLE.STEP1)); - Assert.assertNull(collection.getWorkflowStep2(context)); - Assert.assertNull(collection.getWorkflowStep3(context)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - attemptItemClaim(ROLE.SUB, true); - attemptItemClaim(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - - attemptItemUnclaim(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.SUB, true); - attemptItemClaim(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.SUB, true); - attemptItemAdvanceFinal(ROLE.STEP1, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that appropriate claim and advance permissions are enforced for a workflow with only Step 2. - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithStep2AllRoles() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(null, ROLE.STEP2, null); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertNull(collection.getWorkflowStep1(context)); - Assert.assertEquals(collection.getWorkflowStep2(context), roleGroups.get(ROLE.STEP2)); - Assert.assertNull(collection.getWorkflowStep3(context)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP2); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemUnclaim(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP2); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP2); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that appropriate claim permissions are enforced for a workflow with only Step 2. - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithStep2AllRolesClaim() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(null, ROLE.STEP2, null); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertNull(collection.getWorkflowStep1(context)); - Assert.assertEquals(collection.getWorkflowStep2(context), roleGroups.get(ROLE.STEP2)); - Assert.assertNull(collection.getWorkflowStep3(context)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP2); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemUnclaim(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP2); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP2, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that expected permissions are valid for a workflow with only Step 2. - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithStep2ExpectedRoles() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(null, ROLE.STEP2, null); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertNull(collection.getWorkflowStep1(context)); - Assert.assertEquals(collection.getWorkflowStep2(context), roleGroups.get(ROLE.STEP2)); - Assert.assertNull(collection.getWorkflowStep3(context)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemUnclaim(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP2, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that appropriate claim and advance permissions are enforced for a submitter in a workflow with only Step 2. - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithStep2Submitter() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(null, ROLE.STEP2, null); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertNull(collection.getWorkflowStep1(context)); - Assert.assertEquals(collection.getWorkflowStep2(context), roleGroups.get(ROLE.STEP2)); - Assert.assertNull(collection.getWorkflowStep3(context)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - attemptItemClaim(ROLE.SUB, true); - attemptItemClaim(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemUnclaim(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.SUB, true); - attemptItemClaim(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.SUB, true); - attemptItemAdvanceFinal(ROLE.STEP2, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that appropriate claim and advance permissions are enforced for a workflow with only Step 3. - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithStep3AllRoles() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(null, null, ROLE.STEP3); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertNull(collection.getWorkflowStep1(context)); - Assert.assertNull(collection.getWorkflowStep2(context)); - Assert.assertEquals(collection.getWorkflowStep3(context), roleGroups.get(ROLE.STEP3)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP3); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemUnclaim(ROLE.STEP3, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP3); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP3); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that appropriate claim permissions are enforced for a workflow with only Step 3. - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithStep3AllRolesClaim() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(null, null, ROLE.STEP3); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertNull(collection.getWorkflowStep1(context)); - Assert.assertNull(collection.getWorkflowStep2(context)); - Assert.assertEquals(collection.getWorkflowStep3(context), roleGroups.get(ROLE.STEP3)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP3); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemUnclaim(ROLE.STEP3, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP3); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP3, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that expected permissions are valid for a workflow with only Step 3. - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithStep3ExpectedRoles() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(null, null, ROLE.STEP3); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertNull(collection.getWorkflowStep1(context)); - Assert.assertNull(collection.getWorkflowStep2(context)); - Assert.assertEquals(collection.getWorkflowStep3(context), roleGroups.get(ROLE.STEP3)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP3, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemUnclaim(ROLE.STEP3, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP3, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP3, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that appropriate claim and advance permissions are enforced for a submitter in a workflow with only Step 3. - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithStep3Submitter() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(null, null, ROLE.STEP3); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertNull(collection.getWorkflowStep1(context)); - Assert.assertNull(collection.getWorkflowStep2(context)); - Assert.assertEquals(collection.getWorkflowStep3(context), roleGroups.get(ROLE.STEP3)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - attemptItemClaim(ROLE.SUB, true); - attemptItemClaim(ROLE.STEP3, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemUnclaim(ROLE.STEP3, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.SUB, true); - attemptItemClaim(ROLE.STEP3, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.SUB, true); - attemptItemAdvanceFinal(ROLE.STEP3, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that appropriate claim and advance permissions are enforced for a 2 step workflow (1 & 2). - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithSteps12AllRoles() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(ROLE.STEP1, ROLE.STEP2, null); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertEquals(collection.getWorkflowStep1(context), roleGroups.get(ROLE.STEP1)); - Assert.assertEquals(collection.getWorkflowStep2(context), roleGroups.get(ROLE.STEP2)); - Assert.assertNull(collection.getWorkflowStep3(context)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP1); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - attemptItemAdvance(ROLE.STEP1); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP2); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP2); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that expected permissions are valid for a 2 step workflow (1 & 2). - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithSteps12ExpectedRoles() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(ROLE.STEP1, ROLE.STEP2, null); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertEquals(collection.getWorkflowStep1(context), roleGroups.get(ROLE.STEP1)); - Assert.assertEquals(collection.getWorkflowStep2(context), roleGroups.get(ROLE.STEP2)); - Assert.assertNull(collection.getWorkflowStep3(context)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - attemptItemAdvance(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP2, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that appropriate claim and advance permissions are enforced for a submitter in a 2 step workflow (1 & 2). - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithSteps12Submitter() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(ROLE.STEP1, ROLE.STEP2, null); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertEquals(collection.getWorkflowStep1(context), roleGroups.get(ROLE.STEP1)); - Assert.assertEquals(collection.getWorkflowStep2(context), roleGroups.get(ROLE.STEP2)); - Assert.assertNull(collection.getWorkflowStep3(context)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - attemptItemClaim(ROLE.SUB, true); - attemptItemClaim(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - attemptItemAdvance(ROLE.SUB, true); - attemptItemAdvance(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.SUB, true); - attemptItemClaim(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.SUB, true); - attemptItemAdvanceFinal(ROLE.STEP2, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - - /** - * Test that appropriate claim and advance permissions are enforced for a 2 step workflow (1 & 3). - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithSteps13AllRoles() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(ROLE.STEP1, null, ROLE.STEP3); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertEquals(collection.getWorkflowStep1(context), roleGroups.get(ROLE.STEP1)); - Assert.assertNull(collection.getWorkflowStep2(context)); - Assert.assertEquals(collection.getWorkflowStep3(context), roleGroups.get(ROLE.STEP3)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP1); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - attemptItemAdvance(ROLE.STEP1); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP3); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP3); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that expected permissions are valid for a 2 step workflow (1 & 3). - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithSteps13ExpectedRoles() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(ROLE.STEP1, null, ROLE.STEP3); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertEquals(collection.getWorkflowStep1(context), roleGroups.get(ROLE.STEP1)); - Assert.assertNull(collection.getWorkflowStep2(context)); - Assert.assertEquals(collection.getWorkflowStep3(context), roleGroups.get(ROLE.STEP3)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - attemptItemAdvance(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP3, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP3, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - - /** - * Test that appropriate claim and advance permissions are enforced for a submitter in a 2 step workflow (1 & 3). - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithSteps13Submitter() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(ROLE.STEP1, null, ROLE.STEP3); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertEquals(collection.getWorkflowStep1(context), roleGroups.get(ROLE.STEP1)); - Assert.assertNull(collection.getWorkflowStep2(context)); - Assert.assertEquals(collection.getWorkflowStep3(context), roleGroups.get(ROLE.STEP3)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - attemptItemClaim(ROLE.SUB, true); - attemptItemClaim(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - attemptItemAdvance(ROLE.SUB, true); - attemptItemAdvance(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.SUB, true); - attemptItemClaim(ROLE.STEP3, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.SUB, true); - attemptItemAdvanceFinal(ROLE.STEP3, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that appropriate claim and advance permissions are enforced for a 2 step workflow (2 & 3). - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithSteps23AllRoles() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(null, ROLE.STEP2, ROLE.STEP3); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertNull(collection.getWorkflowStep1(context)); - Assert.assertEquals(collection.getWorkflowStep2(context), roleGroups.get(ROLE.STEP2)); - Assert.assertEquals(collection.getWorkflowStep3(context), roleGroups.get(ROLE.STEP3)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP2); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemAdvance(ROLE.STEP2); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP3); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP3); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that expected permissions are valid for a 2 step workflow (2 & 3). - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithSteps23ExpectedRoles() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(null, ROLE.STEP2, ROLE.STEP3); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertNull(collection.getWorkflowStep1(context)); - Assert.assertEquals(collection.getWorkflowStep2(context), roleGroups.get(ROLE.STEP2)); - Assert.assertEquals(collection.getWorkflowStep3(context), roleGroups.get(ROLE.STEP3)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemAdvance(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP3, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP3, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that appropriate claim and advance permissions are enforced for a submitter in a 2 step workflow (2 & 3). - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithSteps23Submitter() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(null, ROLE.STEP2, ROLE.STEP3); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertNull(collection.getWorkflowStep1(context)); - Assert.assertEquals(collection.getWorkflowStep2(context), roleGroups.get(ROLE.STEP2)); - Assert.assertEquals(collection.getWorkflowStep3(context), roleGroups.get(ROLE.STEP3)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - attemptItemClaim(ROLE.SUB, true); - attemptItemClaim(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemAdvance(ROLE.SUB, true); - attemptItemAdvance(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.SUB, true); - attemptItemClaim(ROLE.STEP3, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.SUB, true); - attemptItemAdvanceFinal(ROLE.STEP3, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that appropriate claim and advance permissions are enforced for a 3 step workflow. - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithSteps123AllRoles() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(ROLE.STEP1, ROLE.STEP2, ROLE.STEP3); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertEquals(collection.getWorkflowStep1(context), roleGroups.get(ROLE.STEP1)); - Assert.assertEquals(collection.getWorkflowStep2(context), roleGroups.get(ROLE.STEP2)); - Assert.assertEquals(collection.getWorkflowStep3(context), roleGroups.get(ROLE.STEP3)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP1); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - attemptItemAdvance(ROLE.STEP1); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP2); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemAdvance(ROLE.STEP2); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP3); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP3); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that expected permissions are valid for a 3 step workflow. - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithSteps123ExpectedRoles() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(ROLE.STEP1, ROLE.STEP2, ROLE.STEP3); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertEquals(collection.getWorkflowStep1(context), roleGroups.get(ROLE.STEP1)); - Assert.assertEquals(collection.getWorkflowStep2(context), roleGroups.get(ROLE.STEP2)); - Assert.assertEquals(collection.getWorkflowStep3(context), roleGroups.get(ROLE.STEP3)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - attemptItemClaim(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - attemptItemAdvance(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemAdvance(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.STEP3, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.STEP3, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /** - * Test that appropriate claim and advance permissions are enforced for a submitter in a 3 step workflow. - * - * @throws IOException - * @throws FileNotFoundException - * @throws WorkflowException - */ - @Test - public void testsetWorkflowWithSteps123Submitter() - throws SQLException, AuthorizeException, FileNotFoundException, IOException, WorkflowException { - try { - context.turnOffAuthorisationSystem(); - setStepPermissions(ROLE.STEP1, ROLE.STEP2, ROLE.STEP3); - setupItemAndStartWorkflow(); - } finally { - context.restoreAuthSystemState(); - } - - try { - contextReload(); - Assert.assertEquals(collection.getWorkflowStep1(context), roleGroups.get(ROLE.STEP1)); - Assert.assertEquals(collection.getWorkflowStep2(context), roleGroups.get(ROLE.STEP2)); - Assert.assertEquals(collection.getWorkflowStep3(context), roleGroups.get(ROLE.STEP3)); - - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1POOL, wfi.getState()); - - attemptItemClaim(ROLE.SUB, true); - attemptItemClaim(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP1, wfi.getState()); - - contextReload(); - attemptItemAdvance(ROLE.SUB, true); - attemptItemAdvance(ROLE.STEP1, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.SUB, true); - attemptItemClaim(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP2, wfi.getState()); - - contextReload(); - attemptItemAdvance(ROLE.SUB, true); - attemptItemAdvance(ROLE.STEP2, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3POOL, wfi.getState()); - - contextReload(); - attemptItemClaim(ROLE.SUB, true); - attemptItemClaim(ROLE.STEP3, false); - Assert.assertEquals(BasicWorkflowService.WFSTATE_STEP3, wfi.getState()); - - contextReload(); - attemptItemAdvanceFinal(ROLE.SUB, true); - attemptItemAdvanceFinal(ROLE.STEP3, false); - contextReload(); - } catch (Exception e) { - e.printStackTrace(); - log.error("Exception found in processing", e); - contextReload(); - throw e; - } - } - - /* - * Each user in ROLE.values() will attempt to claim an item. - * Only the user with roleValid should succeed. - */ - public void attemptItemClaim(ROLE roleValid) throws SQLException, AuthorizeException, IOException { - for (ROLE role : ROLE.values()) { - if (role == ROLE.ADMIN || role == roleValid) { - continue; - } - attemptItemClaim(role, true); - } - if (roleValid != null) { - attemptItemClaim(roleValid, false); - } - } - - /* - * Each user in ROLE.values() will attempt to advance an item. - * Only the user with roleValid should succeed. - */ - public void attemptItemAdvance(ROLE roleValid) throws SQLException, AuthorizeException, IOException { - for (ROLE role : ROLE.values()) { - if (role == ROLE.ADMIN || role == roleValid) { - continue; - } - attemptItemAdvance(role, true); - } - if (roleValid != null) { - attemptItemAdvance(roleValid, false); - } - } - - /* - * Each user in ROLE.values() will attempt to advance an item to archived state. - * Only the user with roleValid should succeed. - */ - public void attemptItemAdvanceFinal(ROLE roleValid) throws SQLException, AuthorizeException, IOException { - for (ROLE role : ROLE.values()) { - if (role == ROLE.ADMIN || role == roleValid) { - continue; - } - attemptItemAdvanceFinal(role, true); - } - if (roleValid != null) { - attemptItemAdvanceFinal(roleValid, false); - } - } - - /* - * User role will attempt to claim an item. - * expectFail indicates whether or not the action should succeed. - */ - public void attemptItemClaim(ROLE role, boolean expectAuthFail) - throws SQLException, AuthorizeException, IOException { - EPerson eperson = roleEPersons.get(role); - context.setCurrentUser(eperson); - - int state = wfi.getState(); - if (expectAuthFail) { - try { - basicWorkflowService.claim(context, wfi, eperson); - //If exception is not thrown, owner will be set and state will change - } catch (AuthorizeException e) { - context.abort(); - } catch (Exception e) { - //handle hibernate exception triggered by database rule - context.abort(); - } - - contextReload(); - - eperson = roleEPersons.get(role); - if (state != wfi.getState()) { - log.error(String.format("USER[%-20s] is able to claim task (state %d -> %d) (unexpected)", - eperson.getFullName(), state, wfi.getState()), new Exception()); - } - - Assert.assertEquals(state, wfi.getState()); - Assert.assertNull(wfi.getOwner()); - } else { - basicWorkflowService.claim(context, wfi, eperson); - contextReload(); - eperson = roleEPersons.get(role); - if (state == wfi.getState()) { - log.error(String.format("USER[%-20s] is unable to claim task (state %d -> %d) (unexpected)", - eperson.getFullName(), state, wfi.getState()), new Exception()); - } - - Assert.assertNotEquals(state, wfi.getState()); - Assert.assertNotNull(wfi.getOwner()); - } - Assert.assertFalse(wfi.getItem().isArchived()); - } - - /* - * User role will attempt to claim an item. - * expectFail indicates whether or not the action should succeed. - */ - public void attemptItemUnclaim(ROLE role, boolean expectAuthFail) - throws SQLException, AuthorizeException, IOException { - EPerson eperson = roleEPersons.get(role); - context.setCurrentUser(eperson); - - int state = wfi.getState(); - if (expectAuthFail) { - try { - basicWorkflowService.unclaim(context, wfi, eperson); - //If exception is not thrown, owner will be set and state will change - } catch (AuthorizeException e) { - context.abort(); - } catch (Exception e) { - //handle hibernate exception triggered by database rule - context.abort(); - } - - contextReload(); - - eperson = roleEPersons.get(role); - if (state != wfi.getState()) { - log.error(String.format("USER[%-20s] is able to unclaim task (state %d -> %d) (unexpected)", - eperson.getFullName(), state, wfi.getState()), new Exception()); - } - - Assert.assertEquals(state, wfi.getState()); - Assert.assertNotNull(wfi.getOwner()); - } else { - basicWorkflowService.unclaim(context, wfi, eperson); - contextReload(); - eperson = roleEPersons.get(role); - if (state == wfi.getState()) { - log.error(String.format("USER[%-20s] is unable to unclaim task (state %d -> %d) (unexpected)", - eperson.getFullName(), state, wfi.getState()), new Exception()); - } - - Assert.assertNotEquals(state, wfi.getState()); - Assert.assertNull(wfi.getOwner()); - } - Assert.assertFalse(wfi.getItem().isArchived()); - } - - /* - * User role will attempt to advance an item. - * expectFail indicates whether or not the action should succeed. - */ - public void attemptItemAdvance(ROLE role, boolean expectAuthFail) - throws SQLException, AuthorizeException, IOException { - EPerson eperson = roleEPersons.get(role); - context.setCurrentUser(eperson); - int state = wfi.getState(); - EPerson owner = wfi.getOwner(); - if (expectAuthFail) { - try { - basicWorkflowService.advance(context, wfi, eperson); - //If exception is not thrown, owner will be unset and state will change - } catch (AuthorizeException e) { - context.abort(); - } catch (Exception e) { - //handle hibernate exception triggered by database rule - context.abort(); - } - contextReload(); - owner = ePersonService.find(context, owner.getID()); - eperson = roleEPersons.get(role); - if (state != wfi.getState()) { - log.error(String.format("USER[%-20s] is able to advance task (state %d -> %d) (unexpected)", - eperson.getFullName(), state, wfi.getState()), new Exception()); - } - Assert.assertEquals(state, wfi.getState()); - Assert.assertEquals(owner, wfi.getOwner()); - } else { - basicWorkflowService.advance(context, wfi, eperson); - contextReload(); - eperson = roleEPersons.get(role); - if (state == wfi.getState()) { - log.error(String.format("USER[%-20s] is unable to advance task (state %d -> %d) (unexpected)", - eperson.getFullName(), state, wfi.getState()), new Exception()); - } - Assert.assertNotEquals(state, wfi.getState()); - Assert.assertNull(wfi.getOwner()); - } - Assert.assertFalse(wfi.getItem().isArchived()); - } - - /* - * User role will attempt to advance an item. - * expectFail indicates whether or not the action should succeed. - */ - public void attemptItemAdvanceFinal(ROLE role, boolean expectAuthFail) - throws SQLException, AuthorizeException, IOException { - EPerson eperson = roleEPersons.get(role); - context.setCurrentUser(eperson); - int state = wfi.getState(); - EPerson owner = wfi.getOwner(); - if (expectAuthFail) { - try { - basicWorkflowService.advance(context, wfi, eperson); - //If exception is not thrown, owner will be unset and state will change - } catch (AuthorizeException e) { - context.abort(); - } catch (Exception e) { - //handle hibernate exception triggered by database rule - context.abort(); - } - contextReload(); - owner = ePersonService.find(context, owner.getID()); - eperson = roleEPersons.get(role); - if (wfi == null) { - log.error(String.format("USER[%-20s] is able to advance task to completion from state %d (unexpected)", - eperson.getFullName(), state), new Exception()); - } - Assert.assertNotNull(wfi); - Assert.assertEquals(state, wfi.getState()); - Assert.assertEquals(owner, wfi.getOwner()); - Assert.assertFalse(wfi.getItem().isArchived()); - } else { - basicWorkflowService.advance(context, wfi, eperson); - contextReload(); - eperson = roleEPersons.get(role); - if (wfi != null) { - log.error(String - .format("USER[%-20s] is unable to advance task to completion from state %d (unexpected)", - eperson.getFullName(), state), new Exception()); - } - Assert.assertNull(wfi); - Assert.assertTrue(item.isArchived()); - } - } - -} diff --git a/dspace-api/src/test/java/org/dspace/xmlworkflow/XmlWorkflowFactoryTest.java b/dspace-api/src/test/java/org/dspace/xmlworkflow/XmlWorkflowFactoryTest.java index 03a6a0e949..cc87f5c443 100644 --- a/dspace-api/src/test/java/org/dspace/xmlworkflow/XmlWorkflowFactoryTest.java +++ b/dspace-api/src/test/java/org/dspace/xmlworkflow/XmlWorkflowFactoryTest.java @@ -23,6 +23,7 @@ import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.CollectionService; import org.dspace.content.service.CommunityService; import org.dspace.utils.DSpace; +import org.dspace.workflow.factory.WorkflowServiceFactoryImpl; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.state.Workflow; import org.junit.After; @@ -30,7 +31,7 @@ import org.junit.Before; import org.junit.Test; /** - * Tests that check that the spring bean {@link org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactoryImpl} + * Tests that check that the spring bean {@link WorkflowServiceFactoryImpl} * in workflow.xml gets created correctly * * @author Maria Verdonck (Atmire) on 19/12/2019 diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClaimedTaskConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClaimedTaskConverter.java index cc7459955f..466776cd18 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClaimedTaskConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClaimedTaskConverter.java @@ -10,9 +10,9 @@ package org.dspace.app.rest.converter; import org.dspace.app.rest.model.ClaimedTaskRest; import org.dspace.app.rest.projection.Projection; import org.dspace.discovery.IndexableObject; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -36,7 +36,7 @@ public class ClaimedTaskConverter public ClaimedTaskRest convert(ClaimedTask obj, Projection projection) { ClaimedTaskRest taskRest = new ClaimedTaskRest(); taskRest.setProjection(projection); - XmlWorkflowItem witem = obj.getWorkflowItem(); + WorkflowItem witem = obj.getWorkflowItem(); taskRest.setId(obj.getID()); taskRest.setWorkflowitem(converter.toRest(witem, projection)); taskRest.setAction(converter.toRest(xmlWorkflowFactory.getActionByName(obj.getActionID()), projection)); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/PoolTaskConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/PoolTaskConverter.java index 48299dd362..6c04108b41 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/PoolTaskConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/PoolTaskConverter.java @@ -10,8 +10,8 @@ package org.dspace.app.rest.converter; import org.dspace.app.rest.model.PoolTaskRest; import org.dspace.app.rest.projection.Projection; import org.dspace.discovery.IndexableObject; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.PoolTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -33,7 +33,7 @@ public class PoolTaskConverter PoolTaskRest taskRest = new PoolTaskRest(); taskRest.setProjection(projection); - XmlWorkflowItem witem = obj.getWorkflowItem(); + WorkflowItem witem = obj.getWorkflowItem(); taskRest.setId(obj.getID()); taskRest.setWorkflowitem(converter.toRest(witem, projection)); if (obj.getEperson() != null) { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/WorkflowItemConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/WorkflowItemConverter.java index 22e902b4ca..4d3dc1954e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/WorkflowItemConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/WorkflowItemConverter.java @@ -11,7 +11,7 @@ import org.dspace.app.rest.model.WorkflowItemRest; import org.dspace.app.rest.projection.Projection; import org.dspace.app.util.SubmissionConfigReaderException; import org.dspace.discovery.IndexableObject; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.workflow.WorkflowItem; import org.springframework.stereotype.Component; /** @@ -23,14 +23,14 @@ import org.springframework.stereotype.Component; */ @Component public class WorkflowItemConverter - extends AInprogressItemConverter { + extends AInprogressItemConverter { public WorkflowItemConverter() throws SubmissionConfigReaderException { super(); } @Override - public WorkflowItemRest convert(XmlWorkflowItem obj, Projection projection) { + public WorkflowItemRest convert(WorkflowItem obj, Projection projection) { WorkflowItemRest witem = new WorkflowItemRest(); witem.setProjection(projection); fillFromModel(obj, witem, projection); @@ -38,12 +38,12 @@ public class WorkflowItemConverter } @Override - public Class getModelClass() { - return XmlWorkflowItem.class; + public Class getModelClass() { + return WorkflowItem.class; } @Override public boolean supportsModel(IndexableObject object) { - return object.getIndexedObject() instanceof XmlWorkflowItem; + return object.getIndexedObject() instanceof WorkflowItem; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java index f5b60eedfc..ce63b1760b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java @@ -33,16 +33,16 @@ import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.service.EPersonService; import org.dspace.workflow.WorkflowException; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowService; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.WorkflowConfigurationException; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; -import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.state.actions.Action; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; @@ -75,7 +75,7 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository wfs; + WorkflowService wfs; @Autowired AuthorizeService authorizeService; @@ -108,7 +108,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { try { long total = wis.countAll(context); - List witems = wis.findAll(context, pageable.getPageNumber(), pageable.getPageSize()); + List witems = wis.findAll(context, pageable.getPageNumber(), pageable.getPageSize()); return converter.toRestPage(witems, pageable, total, utils.obtainProjection()); } catch (SQLException e) { throw new RuntimeException("SQLException in " + this.getClass() + "#findAll trying to retrieve all " + @@ -154,7 +154,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository witems = wis.findBySubmitter(context, ep, pageable.getPageNumber(), + List witems = wis.findBySubmitter(context, ep, pageable.getPageNumber(), pageable.getPageSize()); return converter.toRestPage(witems, pageable, total, utils.obtainProjection()); } catch (SQLException e) { @@ -165,7 +165,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository stringList) { - XmlWorkflowItem source; + WorkflowItem source; if (stringList == null || stringList.isEmpty() || stringList.size() > 1) { throw new UnprocessableEntityException("The given URI list could not be properly parsed to one result"); } @@ -198,7 +198,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository operations = patch.getOperations(); WorkflowItemRest wsi = findOne(context, id); - XmlWorkflowItem source = wis.find(context, id); + WorkflowItem source = wis.find(context, id); this.checkIfEditMetadataAllowedInCurrentStep(context, source); @@ -267,7 +267,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository poolTasks = poolTaskService.find(context, xmlWorkflowItem); - List claimedTasks = claimedTaskService.find(context, xmlWorkflowItem); + List poolTasks = poolTaskService.find(context, workflowItem); + List claimedTasks = claimedTaskService.find(context, workflowItem); for (PoolTask poolTask : poolTasks) { return converter.toRest(xmlWorkflowFactory.getStepByName(poolTask.getStepID()), projection); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/PoolTaskRestPermissionEvaluatorPlugin.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/PoolTaskRestPermissionEvaluatorPlugin.java index d369cffcf9..4e325cfc00 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/PoolTaskRestPermissionEvaluatorPlugin.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/PoolTaskRestPermissionEvaluatorPlugin.java @@ -20,8 +20,8 @@ import org.dspace.eperson.EPerson; import org.dspace.eperson.service.EPersonService; import org.dspace.services.RequestService; import org.dspace.services.model.Request; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.PoolTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -72,7 +72,7 @@ public class PoolTaskRestPermissionEvaluatorPlugin extends RestObjectPermissionE return true; } - XmlWorkflowItem workflowItem = poolTask.getWorkflowItem(); + WorkflowItem workflowItem = poolTask.getWorkflowItem(); PoolTask poolTask2 = poolTaskService.findByWorkflowIdAndEPerson(context, workflowItem, ePerson); if (poolTask2 != null && poolTask2.getID().equals(poolTask.getID())) { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/WorkflowRestPermissionEvaluatorPlugin.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/WorkflowRestPermissionEvaluatorPlugin.java index a4c452d9c3..75f8647135 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/WorkflowRestPermissionEvaluatorPlugin.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/WorkflowRestPermissionEvaluatorPlugin.java @@ -20,10 +20,10 @@ import org.dspace.eperson.EPerson; import org.dspace.eperson.service.EPersonService; import org.dspace.services.RequestService; import org.dspace.services.model.Request; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowItemService; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -45,7 +45,7 @@ public class WorkflowRestPermissionEvaluatorPlugin extends RestObjectPermissionE private RequestService requestService; @Autowired - private XmlWorkflowItemService workflowItemService; + private WorkflowItemService workflowItemService; @Autowired private PoolTaskService poolTaskService; @@ -76,7 +76,7 @@ public class WorkflowRestPermissionEvaluatorPlugin extends RestObjectPermissionE return false; } Integer dsoId = Integer.parseInt(targetId.toString()); - XmlWorkflowItem workflowItem = workflowItemService.find(context, dsoId); + WorkflowItem workflowItem = workflowItemService.find(context, dsoId); // submitter can see their inprogress submission if (ePerson.equals(workflowItem.getSubmitter())) { return true; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/SubmissionService.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/SubmissionService.java index 0ac468448b..b80852e6f3 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/SubmissionService.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/SubmissionService.java @@ -49,9 +49,9 @@ import org.dspace.services.ConfigurationService; import org.dspace.services.RequestService; import org.dspace.services.model.Request; import org.dspace.workflow.WorkflowException; +import org.dspace.workflow.WorkflowItem; import org.dspace.workflow.WorkflowItemService; import org.dspace.workflow.WorkflowService; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.datasource.init.UncategorizedScriptException; import org.springframework.stereotype.Component; @@ -75,9 +75,9 @@ public class SubmissionService { @Autowired protected WorkspaceItemService workspaceItemService; @Autowired - protected WorkflowItemService workflowItemService; + protected WorkflowItemService workflowItemService; @Autowired - protected WorkflowService workflowService; + protected WorkflowService workflowService; @Autowired protected CreativeCommonsService creativeCommonsService; @Autowired @@ -215,9 +215,9 @@ public class SubmissionService { * @throws AuthorizeException * @throws WorkflowException */ - public XmlWorkflowItem createWorkflowItem(Context context, String requestUriListString) + public WorkflowItem createWorkflowItem(Context context, String requestUriListString) throws SQLException, AuthorizeException, WorkflowException { - XmlWorkflowItem wi = null; + WorkflowItem wi = null; if (StringUtils.isBlank(requestUriListString)) { throw new UnprocessableEntityException("Malformed body..." + requestUriListString); } @@ -271,7 +271,7 @@ public class SubmissionService { return accessCondition; } - public void saveWorkflowItem(Context context, XmlWorkflowItem source) throws SQLException, AuthorizeException { + public void saveWorkflowItem(Context context, WorkflowItem source) throws SQLException, AuthorizeException { workflowItemService.update(context, source); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java index bd5ceb75d9..002acbf482 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java @@ -52,8 +52,8 @@ import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.hamcrest.Matchers; import org.junit.Ignore; import org.junit.Test; @@ -3244,7 +3244,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest WorkspaceItem wsItem2 = WorkspaceItemBuilder.createWorkspaceItem(context, col2).withTitle("Workspace Item 2") .build(); - XmlWorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") + WorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") .build(); // 4. a claimed task from the administrator @@ -3259,7 +3259,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest WorkspaceItem wsItem2Admin = WorkspaceItemBuilder.createWorkspaceItem(context, col2) .withTitle("Admin Workspace Item 2").build(); - XmlWorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Admin Workflow Item 1").build(); context.restoreAuthSystemState(); @@ -3380,7 +3380,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .withIssueDate("2010-11-03") .build(); - XmlWorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") + WorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") .withIssueDate("2010-11-03") .build(); @@ -3399,7 +3399,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .withIssueDate("2010-11-03") .withTitle("Admin Workspace Item 2").build(); - XmlWorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) .withIssueDate("2010-11-03") .withTitle("Admin Workflow Item 1").build(); @@ -3583,7 +3583,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .withIssueDate("2010-11-03") .build(); - XmlWorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") + WorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") .withIssueDate("2010-11-03") .build(); @@ -3602,7 +3602,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .withIssueDate("2010-11-03") .withTitle("Admin Workspace Item 2").build(); - XmlWorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) .withIssueDate("2010-11-03") .withTitle("Admin Workflow Item 1").build(); @@ -3853,7 +3853,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .withIssueDate("2010-11-03") .build(); - XmlWorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") + WorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") .withIssueDate("2010-11-03") .build(); @@ -3872,7 +3872,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .withIssueDate("2010-11-03") .withTitle("Admin Workspace Item 2").build(); - XmlWorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) .withIssueDate("2010-11-03") .withTitle("Admin Workflow Item 1").build(); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/LoginAsEPersonIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/LoginAsEPersonIT.java index 95412b514d..f9c58055ef 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/LoginAsEPersonIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/LoginAsEPersonIT.java @@ -40,8 +40,8 @@ import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; import org.dspace.eperson.service.GroupService; import org.dspace.services.ConfigurationService; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.PoolTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; @@ -250,7 +250,7 @@ public class LoginAsEPersonIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem = poolTask.getWorkflowItem(); + WorkflowItem witem = poolTask.getWorkflowItem(); context.restoreAuthSystemState(); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/StatisticsRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/StatisticsRestRepositoryIT.java index 08303e57f2..ef2ac3244e 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/StatisticsRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/StatisticsRestRepositoryIT.java @@ -995,7 +995,7 @@ public class StatisticsRestRepositoryIT extends AbstractControllerIntegrationTes // ** THEN ** .andExpect(status().isOk()) .andExpect(jsonPath("$._embedded.usagereports", not(empty()))) - .andExpect(jsonPath("$._embedded.usagereports", Matchers.containsInAnyOrder( + .andExpect(jsonPath("$._embedded.usagereports", Matchers.hasItems( UsageReportMatcher .matchUsageReport(collectionNotVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID, TOTAL_VISITS_REPORT_ID, @@ -1007,7 +1007,8 @@ public class StatisticsRestRepositoryIT extends AbstractControllerIntegrationTes UsageReportMatcher.matchUsageReport(collectionNotVisited.getID() + "_" + TOP_CITIES_REPORT_ID, TOP_CITIES_REPORT_ID, new ArrayList<>()), UsageReportMatcher.matchUsageReport(collectionNotVisited.getID() + "_" + TOP_COUNTRIES_REPORT_ID, - TOP_COUNTRIES_REPORT_ID, new ArrayList<>())))); + TOP_COUNTRIES_REPORT_ID, new ArrayList<>()) + ))); } @Test diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java index a7813601ec..b699eef709 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java @@ -45,12 +45,12 @@ import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.Item; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.PoolTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.hamcrest.Matchers; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -290,21 +290,21 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //5. our workflow items - XmlWorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 2") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 3") .withIssueDate("2017-10-18") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -434,21 +434,21 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //5. our workflow items - XmlWorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 2") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 3") .withIssueDate("2017-10-18") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -566,7 +566,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem = poolTask.getWorkflowItem(); + WorkflowItem witem = poolTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -640,7 +640,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem = poolTask.getWorkflowItem(); + WorkflowItem witem = poolTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -703,7 +703,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem = poolTask.getWorkflowItem(); + WorkflowItem witem = poolTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -768,7 +768,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -833,7 +833,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -892,7 +892,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -948,7 +948,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1014,7 +1014,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1201,9 +1201,9 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withSubject("ExtraEntry3") .build(); - XmlWorkflowItem witem1 = claimedTask1.getWorkflowItem(); - XmlWorkflowItem witem2 = claimedTask2.getWorkflowItem(); - XmlWorkflowItem witem3 = claimedTask3.getWorkflowItem(); + WorkflowItem witem1 = claimedTask1.getWorkflowItem(); + WorkflowItem witem2 = claimedTask2.getWorkflowItem(); + WorkflowItem witem3 = claimedTask3.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1340,9 +1340,9 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withSubject("ExtraEntry3") .build(); - XmlWorkflowItem witem1 = claimedTask1.getWorkflowItem(); - XmlWorkflowItem witem2 = claimedTask2.getWorkflowItem(); - XmlWorkflowItem witem3 = claimedTask3.getWorkflowItem(); + WorkflowItem witem1 = claimedTask1.getWorkflowItem(); + WorkflowItem witem2 = claimedTask2.getWorkflowItem(); + WorkflowItem witem3 = claimedTask3.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1407,7 +1407,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); Item item = witem.getItem(); context.restoreAuthSystemState(); @@ -1483,7 +1483,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); Item item = witem.getItem(); context.restoreAuthSystemState(); @@ -1548,7 +1548,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); Item item = witem.getItem(); context.restoreAuthSystemState(); @@ -1657,7 +1657,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); Item item = witem.getItem(); context.restoreAuthSystemState(); @@ -1726,7 +1726,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); Item item = witem.getItem(); context.restoreAuthSystemState(); @@ -1800,7 +1800,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2029,7 +2029,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2051,7 +2051,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "reviewstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2074,7 +2074,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { Matchers.allOf( hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2144,7 +2144,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2163,7 +2163,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "reviewstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2186,7 +2186,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { Matchers.allOf( hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2243,7 +2243,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2265,7 +2265,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "editstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2288,7 +2288,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { Matchers.allOf( hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2356,7 +2356,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2378,7 +2378,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "editstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2401,7 +2401,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { Matchers.allOf( hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2464,7 +2464,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2486,7 +2486,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "finaleditstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2509,7 +2509,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { Matchers.allOf( hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2572,7 +2572,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2594,7 +2594,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "finaleditstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2617,7 +2617,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { Matchers.allOf( hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2670,7 +2670,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2692,7 +2692,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "finaleditstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2715,7 +2715,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { Matchers.allOf( hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2782,7 +2782,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem witem = poolTask.getWorkflowItem(); + WorkflowItem witem = poolTask.getWorkflowItem(); poolTask.setStepID("editstep"); poolTask.setActionID("editaction"); @@ -2835,7 +2835,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2854,7 +2854,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "editstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2924,7 +2924,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .build(); claimedTask.setStepID("reviewstep"); claimedTask.setActionID("reviewaction"); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -2982,7 +2982,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -3001,7 +3001,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "reviewstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -3076,7 +3076,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .build(); claimedTask.setStepID("editstep"); claimedTask.setActionID("editaction"); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); String reviewer1Token = getAuthToken(reviewer1.getEmail(), password); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowActionRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowActionRestRepositoryIT.java index 884fc6cfa5..369d317698 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowActionRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowActionRestRepositoryIT.java @@ -17,8 +17,8 @@ import org.dspace.app.rest.matcher.WorkflowActionMatcher; import org.dspace.app.rest.model.WorkflowActionRest; import org.dspace.app.rest.repository.WorkflowActionRestRepository; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.hamcrest.Matchers; import org.junit.Test; @@ -30,7 +30,7 @@ import org.junit.Test; */ public class WorkflowActionRestRepositoryIT extends AbstractControllerIntegrationTest { - private XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory(); + private XmlWorkflowFactory xmlWorkflowFactory = WorkflowServiceFactory.getInstance().getWorkflowFactory(); private static final String WORKFLOW_ACTIONS_ENDPOINT = "/api/" + WorkflowActionRest.CATEGORY + "/" + WorkflowActionRest.NAME_PLURAL; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowDefinitionRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowDefinitionRestRepositoryIT.java index 3f7ae74000..7b20485daa 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowDefinitionRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowDefinitionRestRepositoryIT.java @@ -27,8 +27,8 @@ import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.content.Collection; import org.dspace.content.Community; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Workflow; import org.hamcrest.Matchers; import org.junit.Test; @@ -42,7 +42,7 @@ import org.junit.Test; public class WorkflowDefinitionRestRepositoryIT extends AbstractControllerIntegrationTest { private final XmlWorkflowFactory xmlWorkflowFactory - = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory(); + = WorkflowServiceFactory.getInstance().getWorkflowFactory(); private static final String WORKFLOW_DEFINITIONS_ENDPOINT = "/api/" + WorkflowDefinitionRest.CATEGORY + "/" + WorkflowDefinitionRest.NAME_PLURAL; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestRepositoryIT.java index 7a0fe01d4a..760e2df1a2 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestRepositoryIT.java @@ -54,10 +54,10 @@ import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; import org.dspace.eperson.EPerson; import org.dspace.services.ConfigurationService; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Ignore; @@ -112,17 +112,17 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT //2. Three workflow items in two different collections - XmlWorkflowItem workflowItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem workflowItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .build(); - XmlWorkflowItem workflowItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem workflowItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 2") .withIssueDate("2016-02-13") .build(); - XmlWorkflowItem workflowItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem workflowItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 3") .withIssueDate("2016-02-13") .build(); @@ -167,17 +167,17 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(1, admin).build(); //2. Three workflow items in two different collections - XmlWorkflowItem workflowItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem workflowItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .build(); - XmlWorkflowItem workflowItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem workflowItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 2") .withIssueDate("2016-02-13") .build(); - XmlWorkflowItem workflowItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem workflowItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 3") .withIssueDate("2016-02-13") .build(); @@ -237,18 +237,18 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT //2. Three workflow items in two different collections - XmlWorkflowItem workflowItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem workflowItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .build(); // these two items will be visible individually to the user - XmlWorkflowItem workflowItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem workflowItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 2") .withIssueDate("2016-02-13") .build(); - XmlWorkflowItem workflowItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem workflowItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 3") .withIssueDate("2016-02-13") .build(); @@ -286,7 +286,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(1, admin).build(); //2. a workflow item - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -340,30 +340,30 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(3, reviewer3).build(); //2. three workflow items in the three collections (this will lead to pool task) - XmlWorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .build(); - XmlWorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 2") .build(); - XmlWorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col3) + WorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col3) .withTitle("Workflow Item 3") .build(); //3. Three claimed tasks (and corresponding workflowitems) ClaimedTask claimed1 = ClaimedTaskBuilder.createClaimedTask(context, col1, reviewer1).withTitle("Pool 1") .build(); - XmlWorkflowItem wClaimed1 = claimed1.getWorkflowItem(); + WorkflowItem wClaimed1 = claimed1.getWorkflowItem(); ClaimedTask claimed2 = ClaimedTaskBuilder.createClaimedTask(context, col2, reviewer2).withTitle("Pool 2") .build(); - XmlWorkflowItem wClaimed2 = claimed2.getWorkflowItem(); + WorkflowItem wClaimed2 = claimed2.getWorkflowItem(); ClaimedTask claimed3 = ClaimedTaskBuilder.createClaimedTask(context, col3, reviewer3).withTitle("Pool 3") .build(); - XmlWorkflowItem wClaimed3 = claimed3.getWorkflowItem(); + WorkflowItem wClaimed3 = claimed3.getWorkflowItem(); context.restoreAuthSystemState(); @@ -457,7 +457,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(1, admin).build(); //2. a workflow item - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -536,19 +536,19 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT //3. Two workflow items in two different collections - XmlWorkflowItem workspaceItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem workspaceItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .build(); - XmlWorkflowItem workspaceItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem workspaceItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 2") .withIssueDate("2016-02-13") .build(); //4. A workflowitem for the second submitter context.setCurrentUser(submitter2); - XmlWorkflowItem workspaceItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem workspaceItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 3") .withIssueDate("2016-02-13") .build(); @@ -634,7 +634,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT context.setCurrentUser(submitter); //3. a workflow item - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .build(); @@ -864,13 +864,13 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT context.setCurrentUser(submitter); //3. a workflow item will all the required fields - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .build(); //4. a workflow item without the dateissued required field - XmlWorkflowItem witemMissingFields = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witemMissingFields = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .build(); @@ -927,7 +927,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .build(); claimedTask.setStepID("editstep"); claimedTask.setActionID("editaction"); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -988,7 +988,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT context.setCurrentUser(submitter); //3. a workflow item - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withSubject("ExtraEntry") @@ -1054,7 +1054,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .build(); claimedTask.setStepID("editstep"); claimedTask.setActionID("editaction"); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1123,7 +1123,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .build(); claimedTask.setStepID("editstep"); claimedTask.setActionID("editaction"); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); ClaimedTask claimedTask2 = ClaimedTaskBuilder.createClaimedTask(context, col1, eperson) .withTitle("Workflow Item 2") @@ -1135,7 +1135,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .build(); claimedTask2.setStepID("editstep"); claimedTask2.setActionID("editaction"); - XmlWorkflowItem witemMultipleSubjects = claimedTask2.getWorkflowItem(); + WorkflowItem witemMultipleSubjects = claimedTask2.getWorkflowItem(); ClaimedTask claimedTask3 = ClaimedTaskBuilder.createClaimedTask(context, col1, eperson) .withTitle("Workflow Item 3") @@ -1147,7 +1147,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .build(); claimedTask3.setStepID("editstep"); claimedTask3.setActionID("editaction"); - XmlWorkflowItem witemWithTitleDateAndSubjects = claimedTask3.getWorkflowItem(); + WorkflowItem witemWithTitleDateAndSubjects = claimedTask3.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1321,7 +1321,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .build(); claimedTask.setStepID("editstep"); claimedTask.setActionID("editaction"); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1391,7 +1391,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .build(); claimedTask.setStepID("editstep"); claimedTask.setActionID("editaction"); - XmlWorkflowItem witem = claimedTask.getWorkflowItem(); + WorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1586,7 +1586,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(1, admin).build(); //2. a workflow item - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -1646,7 +1646,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT Item item = ItemBuilder.createItem(context, col1).build(); //2. a workspace item - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -1676,7 +1676,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(1, admin).build(); - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -1707,7 +1707,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(1, admin).build(); - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -1753,17 +1753,17 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(3, reviewer3).build(); //2. three workflow items in the three collections (this will lead to pool task) - XmlWorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2016-02-13") .build(); - XmlWorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) + WorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 2") .withIssueDate("2016-02-13") .build(); - XmlWorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col3) + WorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col3) .withTitle("Workflow Item 3") .withIssueDate("2016-02-13") .build(); @@ -1835,7 +1835,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(1, admin).build(); //2. a workflow item - XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowStepRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowStepRestRepositoryIT.java index a9a5b12d94..8399ab9373 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowStepRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowStepRestRepositoryIT.java @@ -15,8 +15,8 @@ import org.dspace.app.rest.matcher.WorkflowStepMatcher; import org.dspace.app.rest.model.WorkflowStepRest; import org.dspace.app.rest.repository.WorkflowStepRestRepository; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Step; import org.hamcrest.Matchers; import org.junit.Test; @@ -28,7 +28,7 @@ import org.junit.Test; */ public class WorkflowStepRestRepositoryIT extends AbstractControllerIntegrationTest { - private XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory(); + private XmlWorkflowFactory xmlWorkflowFactory = WorkflowServiceFactory.getInstance().getWorkflowFactory(); private static final String WORKFLOW_ACTIONS_ENDPOINT = "/api/" + WorkflowStepRest.CATEGORY + "/" + WorkflowStepRest.NAME_PLURAL; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/eperson/DeleteEPersonSubmitterIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/eperson/DeleteEPersonSubmitterIT.java index e280bffdef..304ed5033b 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/eperson/DeleteEPersonSubmitterIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/eperson/DeleteEPersonSubmitterIT.java @@ -50,10 +50,10 @@ import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.versioning.Version; import org.dspace.versioning.factory.VersionServiceFactory; import org.dspace.versioning.service.VersioningService; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; -import org.dspace.xmlworkflow.service.XmlWorkflowService; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.WorkflowService; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; @@ -68,9 +68,9 @@ public class DeleteEPersonSubmitterIT extends AbstractControllerIntegrationTest protected InstallItemService installItemService = ContentServiceFactory.getInstance().getInstallItemService(); protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance() .getWorkspaceItemService(); - protected XmlWorkflowService xmlWorkflowService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); - protected XmlWorkflowItemService xmlWorkflowItemService = XmlWorkflowServiceFactory.getInstance() - .getXmlWorkflowItemService(); + protected WorkflowService workflowService = WorkflowServiceFactory.getInstance().getWorkflowService(); + protected WorkflowItemService workflowItemService = WorkflowServiceFactory.getInstance() + .getWorkflowItemService(); protected VersioningService versioningService = VersionServiceFactory.getInstance().getVersionService(); protected RequestItemAuthorExtractor requestItemAuthorExtractor = @@ -315,7 +315,7 @@ public class DeleteEPersonSubmitterIT extends AbstractControllerIntegrationTest .withWorkflowGroup(1, workflowUser) .build(); - XmlWorkflowItem workflowItem = WorkflowItemBuilder.createWorkflowItem(context, collection) + WorkflowItem workflowItem = WorkflowItemBuilder.createWorkflowItem(context, collection) .withSubmitter(submitter) .withTitle("Test Item") .withIssueDate("2019-03-06") diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowDefinitionMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowDefinitionMatcher.java index 02712ee3a2..268948ad2c 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowDefinitionMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowDefinitionMatcher.java @@ -15,8 +15,8 @@ import static org.hamcrest.Matchers.is; import java.util.UUID; import org.dspace.app.rest.model.WorkflowDefinitionRest; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Workflow; import org.hamcrest.Matcher; import org.hamcrest.Matchers; @@ -26,7 +26,7 @@ import org.hamcrest.Matchers; */ public class WorkflowDefinitionMatcher { - private static XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory(); + private static XmlWorkflowFactory xmlWorkflowFactory = WorkflowServiceFactory.getInstance().getWorkflowFactory(); private static final String WORKFLOW_DEFINITIONS_ENDPOINT = "/api/" + WorkflowDefinitionRest.CATEGORY + "/" + WorkflowDefinitionRest.NAME_PLURAL + "/"; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowItemMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowItemMatcher.java index 7a1b0fcb92..7fd8fa0926 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowItemMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowItemMatcher.java @@ -14,7 +14,7 @@ import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.startsWith; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.workflow.WorkflowItem; import org.hamcrest.Matcher; /** @@ -38,8 +38,8 @@ public class WorkflowItemMatcher { * the dc.date.issued * @return */ - public static Matcher matchItemWithTitleAndDateIssued(XmlWorkflowItem witem, String title, - String dateIssued) { + public static Matcher matchItemWithTitleAndDateIssued(WorkflowItem witem, String title, + String dateIssued) { return allOf( // Check workflowitem properties matchProperties(witem), @@ -64,9 +64,9 @@ public class WorkflowItemMatcher { * * @return */ - public static Matcher matchItemWithTitleAndDateIssuedAndSubject(XmlWorkflowItem witem, String title, - String dateIssued, - String subject) { + public static Matcher matchItemWithTitleAndDateIssuedAndSubject(WorkflowItem witem, String title, + String dateIssued, + String subject) { return allOf( // Check workspaceitem properties matchProperties(witem), @@ -88,7 +88,7 @@ public class WorkflowItemMatcher { * the workflowitem * @return */ - public static Matcher matchProperties(XmlWorkflowItem witem) { + public static Matcher matchProperties(WorkflowItem witem) { return allOf( witem != null ? hasJsonPath("$.id", is(witem.getID())) : hasJsonPath("$.id"), hasJsonPath("$.type", is("workflowitem")) @@ -102,7 +102,7 @@ public class WorkflowItemMatcher { * the workflowitem * @return */ - public static Matcher matchLinks(XmlWorkflowItem witem) { + public static Matcher matchLinks(WorkflowItem witem) { return allOf( witem != null ? hasJsonPath("$._links.self.href", diff --git a/dspace/bin/dspace-info.pl b/dspace/bin/dspace-info.pl index e539ef2846..5851eab0f1 100755 --- a/dspace/bin/dspace-info.pl +++ b/dspace/bin/dspace-info.pl @@ -53,17 +53,17 @@ die "Cannot find dspace directory tree $dspace_dir - edit dspace-info.pl 'dspace # count DSpace objects ###################### -my $bitstream_count = CountRows( "bitstream" ); -my $bundle_count = CountRows( "bundle" ); -my $collection_count = CountRows( "collection" ); -my $community_count = CountRows( "community" ); -my $dcvalue_count = CountRows( "dcvalue" ); -my $eperson_count = CountRows( "eperson" ); -my $item_count = CountRows( "item" ); -my $handle_count = CountRows( "handle" ); -my $group_count = CountRows( "epersongroup" ); -my $workflowitem_count = CountRows( "workflowitem" ); -my $workspaceitem_count = CountRows( "workspaceitem" ); +my $bitstream_count = CountRows( "bitstream" ); +my $bundle_count = CountRows( "bundle" ); +my $collection_count = CountRows( "collection" ); +my $community_count = CountRows( "community" ); +my $dcvalue_count = CountRows( "dcvalue" ); +my $eperson_count = CountRows( "eperson" ); +my $item_count = CountRows( "item" ); +my $handle_count = CountRows( "handle" ); +my $group_count = CountRows( "epersongroup" ); +my $workflowitem_count = CountRows( "cwf_workflowitem"); +my $workspaceitem_count = CountRows( "workspaceitem" ); # find sizes of dspace directories ########## diff --git a/dspace/config/hibernate.cfg.xml b/dspace/config/hibernate.cfg.xml index 39f5a11378..5ac79c144d 100644 --- a/dspace/config/hibernate.cfg.xml +++ b/dspace/config/hibernate.cfg.xml @@ -80,7 +80,7 @@ - + diff --git a/dspace/config/spring/api/core-dao-services.xml b/dspace/config/spring/api/core-dao-services.xml index 5c68e4fad9..e8cfdf3be9 100644 --- a/dspace/config/spring/api/core-dao-services.xml +++ b/dspace/config/spring/api/core-dao-services.xml @@ -53,15 +53,12 @@ - - - - + diff --git a/dspace/config/spring/api/core-factory-services.xml b/dspace/config/spring/api/core-factory-services.xml index 3fc907d226..4883b76da2 100644 --- a/dspace/config/spring/api/core-factory-services.xml +++ b/dspace/config/spring/api/core-factory-services.xml @@ -25,7 +25,6 @@ - @@ -45,7 +44,7 @@ - + diff --git a/dspace/config/spring/api/core-services.xml b/dspace/config/spring/api/core-services.xml index 1af81ad8f6..57edea3ef1 100644 --- a/dspace/config/spring/api/core-services.xml +++ b/dspace/config/spring/api/core-services.xml @@ -74,9 +74,6 @@
- - - @@ -113,8 +110,8 @@ - - + + diff --git a/dspace/config/spring/api/discovery.xml b/dspace/config/spring/api/discovery.xml index 76e5a07239..7245e14ca1 100644 --- a/dspace/config/spring/api/discovery.xml +++ b/dspace/config/spring/api/discovery.xml @@ -702,7 +702,7 @@ - search.resourcetype:Item OR search.resourcetype:WorkspaceItem OR search.resourcetype:XmlWorkflowItem + search.resourcetype:Item OR search.resourcetype:WorkspaceItem OR search.resourcetype:WorkflowItem @@ -855,7 +855,7 @@ queries done by discovery for this configuration --> - search.resourcetype:XmlWorkflowItem + search.resourcetype:WorkflowItem From 2109a5878d16fcada44e6be574ecb8f56407dabd Mon Sep 17 00:00:00 2001 From: Bruno Roemers Date: Wed, 27 Jan 2021 15:35:44 +0100 Subject: [PATCH 055/179] 74236: BUGFIX: StartDateLimit and EndDateLimit are both maximum dates They do not represent a range but are independent of each other. Also removed obsolete field selectGroupName. --- .../submit/model/AccessConditionOption.java | 59 +++++++++---------- .../config/spring/api/access-conditions.xml | 11 ---- .../config/spring/api/access-conditions.xml | 10 ---- 3 files changed, 27 insertions(+), 53 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java b/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java index 22898a8a38..b9e9f84438 100644 --- a/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java +++ b/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java @@ -51,16 +51,6 @@ public class AccessConditionOption { */ private String groupName; - /** - * this is in alternative to the {@link #groupName}. The sub-groups listed in - * the DSpace group identified by the name here specified will be available to - * the user to personalize the access condition. They can be for instance - * University Staff, University Students, etc. so that a "restricted access" - * option can be further specified without the need to create separate access - * condition options for each group - */ - private String selectGroupName; - /** * set to true if this option requires a start date to be indicated * for the underlying resource policy to create @@ -119,6 +109,10 @@ public class AccessConditionOption { this.hasEndDate = hasEndDate; } + /** + * Explanation see: {@link #startDateLimit} + * @return startDateLimit + */ public String getStartDateLimit() { return startDateLimit; } @@ -127,6 +121,10 @@ public class AccessConditionOption { this.startDateLimit = startDateLimit; } + /** + * Explanation see: {@link #endDateLimit} + * @return endDateLimit + */ public String getEndDateLimit() { return endDateLimit; } @@ -135,14 +133,17 @@ public class AccessConditionOption { this.endDateLimit = endDateLimit; } - public String getSelectGroupName() { - return selectGroupName; - } - - public void setSelectGroupName(String selectGroupName) { - this.selectGroupName = selectGroupName; - } - + /** + * Create a new resource policy for a bitstream + * @param context DSpace context + * @param b bitstream for which resource policy is created + * @param name name of the resource policy + * @param description description of the resource policy + * @param startDate start date of the resource policy. If {@link #getHasStartDate()} returns false, + * startDate should be null. Otherwise startDate may not be null. + * @param endDate end date of the resource policy. If {@link #getHasEndDate()} returns false, + * endDate should be null. Otherwise endDate may not be null. + */ public void createResourcePolicy(Context context, Bitstream b, String name, String description, Date startDate, Date endDate) throws SQLException, AuthorizeException, ParseException { @@ -159,9 +160,9 @@ public class AccessConditionOption { throw new IllegalStateException("The access condition " + getName() + " cannot contain an end date."); } - Date earliestStartDate = null; + Date latestStartDate = null; if (getStartDateLimit() != null) { - earliestStartDate = dateMathParser.parseMath(getStartDateLimit()); + latestStartDate = dateMathParser.parseMath(getStartDateLimit()); } Date latestEndDate = null; @@ -169,25 +170,19 @@ public class AccessConditionOption { latestEndDate = dateMathParser.parseMath(getEndDateLimit()); } - // throw if latestEndDate before earliestStartDate - if (earliestStartDate != null && latestEndDate != null && earliestStartDate.compareTo(latestEndDate) > 0) { + // throw if startDate after latestStartDate + if (startDate != null && latestStartDate != null && startDate.after(latestStartDate)) { throw new IllegalStateException(String.format( - "The boundaries of %s overlap: [%s, %s]", getName(), getStartDateLimit(), getEndDateLimit() - )); - } - - // throw if startDate before earliestStartDate - if (earliestStartDate != null && earliestStartDate.compareTo(startDate) > 0) { - throw new IllegalStateException(String.format( - "The start date of access condition %s should be later than %s from now.", + "The start date of access condition %s should be earlier than %s from now.", getName(), getStartDateLimit() )); } // throw if endDate after latestEndDate - if (latestEndDate != null && latestEndDate.compareTo(endDate) < 0) { + if (endDate != null && latestEndDate != null && endDate.after(latestEndDate)) { throw new IllegalStateException(String.format( - "The end date of access condition %s should be earlier than %s from now.", getName(), getEndDateLimit() + "The end date of access condition %s should be earlier than %s from now.", + getName(), getEndDateLimit() )); } diff --git a/dspace-api/src/test/data/dspaceFolder/config/spring/api/access-conditions.xml b/dspace-api/src/test/data/dspaceFolder/config/spring/api/access-conditions.xml index b734c78937..f84797806b 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/spring/api/access-conditions.xml +++ b/dspace-api/src/test/data/dspaceFolder/config/spring/api/access-conditions.xml @@ -28,11 +28,6 @@ - @@ -40,11 +35,6 @@ - @@ -52,7 +42,6 @@ - diff --git a/dspace/config/spring/api/access-conditions.xml b/dspace/config/spring/api/access-conditions.xml index be8477c55c..54e58f2e65 100644 --- a/dspace/config/spring/api/access-conditions.xml +++ b/dspace/config/spring/api/access-conditions.xml @@ -27,11 +27,6 @@ - @@ -39,11 +34,6 @@ - From b64711253a296c52f4cdc3965a67e3d94aa5091b Mon Sep 17 00:00:00 2001 From: Bruno Roemers Date: Wed, 27 Jan 2021 15:51:30 +0100 Subject: [PATCH 056/179] 74236: Remove obsolete bean and IT test --- .../config/spring/api/access-conditions.xml | 10 +--- .../rest/WorkspaceItemRestRepositoryIT.java | 60 ------------------- 2 files changed, 1 insertion(+), 69 deletions(-) diff --git a/dspace-api/src/test/data/dspaceFolder/config/spring/api/access-conditions.xml b/dspace-api/src/test/data/dspaceFolder/config/spring/api/access-conditions.xml index f84797806b..d65167a562 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/spring/api/access-conditions.xml +++ b/dspace-api/src/test/data/dspaceFolder/config/spring/api/access-conditions.xml @@ -13,7 +13,6 @@ - @@ -39,14 +38,7 @@ - - - - - - - - + diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java index 14bc1d0a09..f1d831c948 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java @@ -3280,66 +3280,6 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration ; } - @Test - @Ignore - public void patchUploadAddAccessConditionTest() throws Exception { - context.turnOffAuthorisationSystem(); - - parentCommunity = CommunityBuilder.createCommunity(context) - .withName("Parent Community") - .build(); - - Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) - .withName("Sub Community") - .build(); - - Collection collection1 = CollectionBuilder.createCollection(context, child1) - .withName("Collection 1") - .build(); - - InputStream pdf = getClass().getResourceAsStream("simple-article.pdf"); - - WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, collection1) - .withTitle("Test WorkspaceItem") - .withIssueDate("2019-10-01") - .withFulltext("simple-article.pdf", "/local/path/simple-article.pdf", pdf) - .build(); - - context.restoreAuthSystemState(); - - // create a list of values to use in add accessCondition - List addAccessCondition = new ArrayList(); - Map value = new HashMap(); - value.put("name", "embargoedWithGroupSelect"); - value.put("groupUUID", embargoedGroup1.getID().toString()); - value.put("endDate", "2030-10-02"); - addAccessCondition.add(new AddOperation("/sections/upload/files/0/accessConditions/-", value)); - - String patchBody = getPatchContent(addAccessCondition); - String authToken = getAuthToken(eperson.getEmail(), password); - - getClient(authToken).perform(patch("/api/submission/workspaceitems/" + witem.getID()) - .content(patchBody) - .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$",Matchers.allOf( - hasJsonPath("$.sections.upload.files[0].accessConditions[0].name", - is("embargoedWithGroupSelect")), - hasJsonPath("$.sections.upload.files[0].accessConditions[0].groupUUID", - is(embargoedGroup1.getID().toString())) - ))); - - // verify that the patch changes have been persisted - getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$",Matchers.allOf( - hasJsonPath("$.sections.upload.files[0].accessConditions[0].name", - is("embargoedWithGroupSelect")), - hasJsonPath("$.sections.upload.files[0].accessConditions[0].groupUUID", - is(embargoedGroup1.getID().toString())) - ))); - } - @Test @Ignore public void patchUploadRemoveAccessConditionTest() throws Exception { From 2cb50b7f4270449560118e3f2919f4dfd7a9a8c6 Mon Sep 17 00:00:00 2001 From: Bruno Roemers Date: Wed, 27 Jan 2021 17:12:32 +0100 Subject: [PATCH 057/179] 74236: Update ITs --- .../rest/WorkspaceItemRestRepositoryIT.java | 137 ++++++++++++++---- 1 file changed, 106 insertions(+), 31 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java index f1d831c948..21149ae79b 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java @@ -11,6 +11,7 @@ import static com.jayway.jsonpath.JsonPath.read; import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadata; import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; @@ -3281,7 +3282,6 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration } @Test - @Ignore public void patchUploadRemoveAccessConditionTest() throws Exception { context.turnOffAuthorisationSystem(); @@ -3309,7 +3309,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration // date SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd"); - Date startDate = DateUtils.addYears(new Date(), 4); + Date startDate = new Date(); String startDateStr = dateFmt.format(startDate); // create a list of values to use in add operation @@ -3344,7 +3344,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration List removeAccessCondition = new ArrayList<>(); removeAccessCondition.add(new RemoveOperation("/sections/upload/files/0/accessConditions")); - // remove and verify that access conditions are set to defaults + // remove and verify that access conditions are removed String patchReplaceBody = getPatchContent(removeAccessCondition); getClient(authToken) .perform( @@ -3353,16 +3353,12 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration .contentType(MediaType.APPLICATION_JSON_PATCH_JSON) ) .andExpect(status().isOk()) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", nullValue())) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", nullValue())); + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions", empty())); // verify that the patch changes have been persisted getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID())) .andExpect(status().isOk()) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", nullValue())) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", nullValue())); + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions", empty())); } @Test @@ -4615,9 +4611,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration } - // TODO: remove ignore @Test - @Ignore public void uploadBitstreamWithoutAccessConditions() throws Exception { context.turnOffAuthorisationSystem(); Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); @@ -4637,14 +4631,13 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration getClient(authToken) .perform(fileUpload("/api/submission/workspaceitems/" + wItem.getID()).file(pdfFile)) .andExpect(status().isCreated()) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))); - // TODO: currently no access conditions are created by default + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions", empty())); // verify that access conditions have been persisted getClient(authToken) .perform(get("/api/submission/workspaceitems/" + wItem.getID())) .andExpect(status().isOk()) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))); + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions", empty())); } // TODO: remove ignore @@ -4726,7 +4719,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration } @Test - public void patchBitstreamWithAccessConditionLeaseAndEndDate() throws Exception { + public void patchBitstreamWithAccessConditionLeaseAndValidEndDate() throws Exception { context.turnOffAuthorisationSystem(); Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build(); @@ -4774,7 +4767,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration } @Test - public void patchBitstreamWithAccessConditionEmbargoAndStartDate() throws Exception { + public void patchBitstreamWithAccessConditionLeaseAndInvalidEndDate() throws Exception { context.turnOffAuthorisationSystem(); Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build(); @@ -4789,7 +4782,53 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration // date SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd"); - Date startDate = DateUtils.addYears(new Date(), 4); + Date endDate = DateUtils.addDays( + // lease ends 1 day too late + DateUtils.addMonths(new Date(), 6), 1 + ); + String endDateStr = dateFmt.format(endDate); + + // prepare patch body + Map accessCondition = new HashMap<>(); + accessCondition.put("name", "lease"); + accessCondition.put("endDate", endDateStr); + List ops = new ArrayList<>(); + ops.add(new AddOperation("/sections/upload/files/0/accessConditions/-", accessCondition)); + String patchBody = getPatchContent(ops); + + // submit patch and verify response + getClient(authToken) + .perform( + patch("/api/submission/workspaceitems/" + wItem.getID()) + .content(patchBody) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON) + ) + .andExpect(status().isInternalServerError()); + + // verify that access conditions array is still empty + getClient(authToken) + .perform(get("/api/submission/workspaceitems/" + wItem.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions", empty())); + } + + @Test + public void patchBitstreamWithAccessConditionEmbargoAndValidStartDate() throws Exception { + context.turnOffAuthorisationSystem(); + Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build(); + InputStream pdf = getClass().getResourceAsStream("simple-article.pdf"); + WorkspaceItem wItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection) + .withFulltext("upload.pdf", "/local/path/simple-article.pdf", pdf) + .build(); + context.restoreAuthSystemState(); + + // auth + String authToken = getAuthToken(eperson.getEmail(), password); + + // date + SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd"); + Date startDate = new Date(); String startDateStr = dateFmt.format(startDate); // prepare patch body @@ -4821,9 +4860,53 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", nullValue())); } - // TODO: remove ignore @Test - @Ignore + public void patchBitstreamWithAccessConditionEmbargoAndInvalidStartDate() throws Exception { + context.turnOffAuthorisationSystem(); + Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build(); + InputStream pdf = getClass().getResourceAsStream("simple-article.pdf"); + WorkspaceItem wItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection) + .withFulltext("upload.pdf", "/local/path/simple-article.pdf", pdf) + .build(); + context.restoreAuthSystemState(); + + // auth + String authToken = getAuthToken(eperson.getEmail(), password); + + // date + SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd"); + Date startDate = DateUtils.addDays( + // embargo ends 1 day too late + DateUtils.addMonths(new Date(), 36), 1 + ); + String startDateStr = dateFmt.format(startDate); + + // prepare patch body + Map accessCondition = new HashMap<>(); + accessCondition.put("name", "embargo"); + accessCondition.put("startDate", startDateStr); + List ops = new ArrayList<>(); + ops.add(new AddOperation("/sections/upload/files/0/accessConditions/-", accessCondition)); + String patchBody = getPatchContent(ops); + + // submit patch and verify response + getClient(authToken) + .perform( + patch("/api/submission/workspaceitems/" + wItem.getID()) + .content(patchBody) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON) + ) + .andExpect(status().isInternalServerError()); + + // verify that access conditions have been persisted + getClient(authToken) + .perform(get("/api/submission/workspaceitems/" + wItem.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions", empty())); + } + + @Test public void patchBitstreamWithAccessConditionOpenAccessAndStartDate() throws Exception { context.turnOffAuthorisationSystem(); Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); @@ -4859,20 +4942,14 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration ) .andExpect(status().isInternalServerError()); - // verify that access conditions have not been modified - // TODO: would be better if the initial access condition is not openaccess, but the builder does not seem to - // support that + // verify that access conditions array is still empty getClient(authToken) .perform(get("/api/submission/workspaceitems/" + wItem.getID())) .andExpect(status().isOk()) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", nullValue())) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", nullValue())); + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions", empty())); } - // TODO: remove ignore @Test - @Ignore public void patchBitstreamWithAccessConditionLease() throws Exception { context.turnOffAuthorisationSystem(); Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); @@ -4902,13 +4979,11 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration ) .andExpect(status().isInternalServerError()); - // verify that access conditions have been persisted + // verify that access conditions array is still empty getClient(authToken) .perform(get("/api/submission/workspaceitems/" + wItem.getID())) .andExpect(status().isOk()) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].startDate", nullValue())) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].endDate", nullValue())); + .andExpect(jsonPath("$.sections.upload.files[0].accessConditions", empty())); } } From ad2bf1f66a3d9c7de937dd9bf8ce32b142fb28ea Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Thu, 28 Jan 2021 09:52:51 +0100 Subject: [PATCH 058/179] Note that this was never implemented --- .../java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java index 21149ae79b..8dfbc8d6bd 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java @@ -4640,7 +4640,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration .andExpect(jsonPath("$.sections.upload.files[0].accessConditions", empty())); } - // TODO: remove ignore + // The REST endpoint doesn't seem to support uploading a bitstream with the access conditions @Test @Ignore public void uploadBitstreamWithAccessConditionOpenAccess() throws Exception { From 55240210893f094f72cb48ab7dda7663fd8c4437 Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Thu, 28 Jan 2021 14:41:09 +0100 Subject: [PATCH 059/179] Test metadata value cache --- .../main/java/org/dspace/content/Item.java | 42 ++++++++++----- .../org/dspace/content/ItemServiceImpl.java | 51 ++++++++----------- 2 files changed, 51 insertions(+), 42 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/Item.java b/dspace-api/src/main/java/org/dspace/content/Item.java index 22a9a4de52..e38611d4e6 100644 --- a/dspace-api/src/main/java/org/dspace/content/Item.java +++ b/dspace-api/src/main/java/org/dspace/content/Item.java @@ -13,19 +13,8 @@ import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; -import javax.persistence.CascadeType; -import javax.persistence.Column; +import javax.persistence.*; import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; -import javax.persistence.Transient; import org.apache.log4j.Logger; import org.dspace.content.comparator.NameAscendingComparator; @@ -112,6 +101,16 @@ public class Item extends DSpaceObject implements DSpaceObjectLegacySupport { @Transient private transient ItemService itemService; + /** + * True if anything else was changed since last metadata retrieval() + * (to drive metadata cache) + */ + @Transient + private boolean modifiedMetadataCache = false; + + @Transient + private List cachedMetadata = new ArrayList<>(); + /** * Protected constructor, create object using: * {@link org.dspace.content.service.ItemService#create(Context, WorkspaceItem)} @@ -373,4 +372,23 @@ public class Item extends DSpaceObject implements DSpaceObjectLegacySupport { } return itemService; } + + @Override + protected void setMetadataModified() { + super.setMetadataModified(); + modifiedMetadataCache = true; + } + + public boolean isModifiedMetadataCache() { + return modifiedMetadataCache; + } + + protected List getCachedMetadata() { + return cachedMetadata; + } + + protected void setCachedMetadata(List cachedMetadata) { + this.cachedMetadata = cachedMetadata; + modifiedMetadataCache = false; + } } diff --git a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java index a2e9553ba5..36f92e4f8e 100644 --- a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java @@ -1328,42 +1328,33 @@ prevent the generation of resource policy entry values with null dspace_object a @Override public List getMetadata(Item item, String schema, String element, String qualifier, String lang, boolean enableVirtualMetadata) { - //Fields of the relation schema are virtual metadata - //except for relation.type which is the type of item in the model - if (StringUtils.equals(schema, MetadataSchemaEnum.RELATION.getName()) && !StringUtils.equals(element, "type")) { - - List relationMetadata = relationshipMetadataService - .getRelationshipMetadata(item, enableVirtualMetadata); - List listToReturn = new LinkedList<>(); - for (MetadataValue metadataValue : relationMetadata) { - if (StringUtils.equals(metadataValue.getMetadataField().getElement(), element)) { - listToReturn.add(metadataValue); - } - } - listToReturn = sortMetadataValueList(listToReturn); - - return listToReturn; - - } else { - List dbMetadataValues = super.getMetadata(item, schema, element, qualifier, lang); + if (!enableVirtualMetadata) { + log.debug("Called getMetadata for " + item.getID() + " without enableVirtualMetadata"); + return super.getMetadata(item, schema, element, qualifier, lang); + } + if (item.isModifiedMetadataCache()) { + log.debug("Called getMetadata for " + item.getID() + " with invalid cache"); + //rebuild cache + List dbMetadataValues = item.getMetadata(); List fullMetadataValueList = new LinkedList<>(); - if (enableVirtualMetadata) { - fullMetadataValueList.addAll(relationshipMetadataService.getRelationshipMetadata(item, true)); - - } + fullMetadataValueList.addAll(relationshipMetadataService.getRelationshipMetadata(item, true)); fullMetadataValueList.addAll(dbMetadataValues); - List finalList = new LinkedList<>(); - for (MetadataValue metadataValue : fullMetadataValueList) { - if (match(schema, element, qualifier, lang, metadataValue)) { - finalList.add(metadataValue); - } - } - finalList = sortMetadataValueList(finalList); - return finalList; + item.setCachedMetadata(sortMetadataValueList(fullMetadataValueList)); } + log.debug("Called getMetadata for " + item.getID() + " based on cache"); + // Build up list of matching values based on the cache + List values = new ArrayList<>(); + for (MetadataValue dcv : item.getCachedMetadata()) { + if (match(schema, element, qualifier, lang, dcv)) { + values.add(dcv); + } + } + + // Create an array of matching values + return values; } /** From a58905d8ed5cdac78287cafe6573834ae342d10e Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Thu, 28 Jan 2021 15:10:10 +0100 Subject: [PATCH 060/179] Test metadata value cache --- dspace-api/src/main/java/org/dspace/content/Item.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/content/Item.java b/dspace-api/src/main/java/org/dspace/content/Item.java index e38611d4e6..6c07329f12 100644 --- a/dspace-api/src/main/java/org/dspace/content/Item.java +++ b/dspace-api/src/main/java/org/dspace/content/Item.java @@ -106,7 +106,7 @@ public class Item extends DSpaceObject implements DSpaceObjectLegacySupport { * (to drive metadata cache) */ @Transient - private boolean modifiedMetadataCache = false; + private boolean modifiedMetadataCache = true; @Transient private List cachedMetadata = new ArrayList<>(); From e32fd1fc4c0586f2c5db60b1cfcf7c0775aecc94 Mon Sep 17 00:00:00 2001 From: Marie Verdonck Date: Fri, 29 Jan 2021 17:23:49 +0100 Subject: [PATCH 061/179] 76575: ITs for deleting items and populating virtual metadata --- .../content/RelationshipServiceImpl.java | 2 +- .../rest/repository/ItemRestRepository.java | 17 +- .../dspace/app/rest/ItemRestRepositoryIT.java | 289 +++++++++++++++--- 3 files changed, 254 insertions(+), 54 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/RelationshipServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/RelationshipServiceImpl.java index 3278ea75f4..82418a26cf 100644 --- a/dspace-api/src/main/java/org/dspace/content/RelationshipServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/RelationshipServiceImpl.java @@ -377,7 +377,7 @@ public class RelationshipServiceImpl implements RelationshipService { authorizeService.authorizeActionBoolean(context, relationship.getRightItem(), Constants.WRITE)) { relationshipDAO.delete(context, relationship); updatePlaceInRelationship(context, relationship); - updateItemsInRelationship(context, relationship); + updateItemsInRelationship(context, relationship); } else { throw new AuthorizeException( "You do not have write rights on this relationship's items"); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java index c6643496ae..6b183950b5 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemRestRepository.java @@ -63,9 +63,9 @@ public class ItemRestRepository extends DSpaceObjectRestRepository Date: Wed, 3 Feb 2021 13:07:21 +0100 Subject: [PATCH 062/179] Fixing issues with the latest main merge --- .../org/dspace/discovery/DiscoveryIT.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java b/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java index 05ff5ae41a..5bb48df652 100644 --- a/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java +++ b/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java @@ -36,16 +36,16 @@ import org.dspace.discovery.indexobject.IndexableWorkspaceItem; import org.dspace.eperson.EPerson; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.workflow.WorkflowException; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowService; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.WorkflowConfigurationException; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; -import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.PoolTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; @@ -58,12 +58,12 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase { protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); protected SearchService searchService = SearchUtils.getSearchService(); - XmlWorkflowService workflowService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); + WorkflowService workflowService = WorkflowServiceFactory.getInstance().getWorkflowService(); - WorkflowRequirementsService workflowRequirementsService = XmlWorkflowServiceFactory.getInstance(). + WorkflowRequirementsService workflowRequirementsService = WorkflowServiceFactory.getInstance(). getWorkflowRequirementsService(); - ClaimedTaskService claimedTaskService = XmlWorkflowServiceFactory.getInstance().getClaimedTaskService(); + ClaimedTaskService claimedTaskService = WorkflowServiceFactory.getInstance().getClaimedTaskService(); ItemService itemService = ContentServiceFactory.getInstance().getItemService(); @@ -138,7 +138,7 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase { Collection collection = CollectionBuilder.createCollection(context, community) .withWorkflowGroup(1, admin) .build(); - Workflow workflow = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory().getWorkflow(collection); + Workflow workflow = WorkflowServiceFactory.getInstance().getWorkflowFactory().getWorkflow(collection); ClaimedTask taskToApprove = ClaimedTaskBuilder.createClaimedTask(context, collection, admin) .withTitle("Test workflow item to approve") @@ -160,7 +160,7 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase { .withIssueDate("2019-03-06") .withSubject("ExtraEntry") .build(); - XmlWorkflowItem wfiToDelete = WorkflowItemBuilder.createWorkflowItem(context, collection) + WorkflowItem wfiToDelete = WorkflowItemBuilder.createWorkflowItem(context, collection) .withTitle("Test workflow item to return") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -253,7 +253,7 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase { throws SQLException, AuthorizeException, IOException, WorkflowException, SearchServiceException { context.turnOffAuthorisationSystem(); workspaceItem = context.reloadEntity(workspaceItem); - XmlWorkflowItem workflowItem = workflowService.startWithoutNotify(context, workspaceItem); + WorkflowItem workflowItem = workflowService.startWithoutNotify(context, workspaceItem); context.commit(); indexer.commit(); context.restoreAuthSystemState(); @@ -269,7 +269,7 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase { context.restoreAuthSystemState(); } - private void deleteWorkflowItem(XmlWorkflowItem workflowItem) + private void deleteWorkflowItem(WorkflowItem workflowItem) throws SQLException, AuthorizeException, IOException, SearchServiceException { context.turnOffAuthorisationSystem(); workflowItem = context.reloadEntity(workflowItem); @@ -284,7 +284,7 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase { final EPerson previousUser = context.getCurrentUser(); taskToUnclaim = context.reloadEntity(taskToUnclaim); context.setCurrentUser(taskToUnclaim.getOwner()); - XmlWorkflowItem workflowItem = taskToUnclaim.getWorkflowItem(); + WorkflowItem workflowItem = taskToUnclaim.getWorkflowItem(); workflowService.deleteClaimedTask(context, workflowItem, taskToUnclaim); workflowRequirementsService.removeClaimedUser(context, workflowItem, taskToUnclaim.getOwner(), taskToUnclaim.getStepID()); @@ -318,7 +318,7 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase { context.setCurrentUser(previousUser); } - private void abort(XmlWorkflowItem workflowItem) + private void abort(WorkflowItem workflowItem) throws SQLException, AuthorizeException, IOException, SearchServiceException { final EPerson previousUser = context.getCurrentUser(); workflowItem = context.reloadEntity(workflowItem); From adc98563d717bfc12d8da6ab8296b497909c906c Mon Sep 17 00:00:00 2001 From: Kevin Van de Velde Date: Wed, 3 Feb 2021 13:10:36 +0100 Subject: [PATCH 063/179] Fixing issues with the latest main merge --- .../test/java/org/dspace/builder/WorkspaceItemBuilder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/builder/WorkspaceItemBuilder.java b/dspace-api/src/test/java/org/dspace/builder/WorkspaceItemBuilder.java index 612ad82faa..e346ab4587 100644 --- a/dspace-api/src/test/java/org/dspace/builder/WorkspaceItemBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/WorkspaceItemBuilder.java @@ -22,7 +22,7 @@ import org.dspace.content.WorkspaceItem; import org.dspace.content.service.WorkspaceItemService; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.workflow.WorkflowItem; /** * Builder to construct WorkspaceItem objects @@ -114,7 +114,7 @@ public class WorkspaceItemBuilder extends AbstractBuilder Date: Fri, 5 Feb 2021 12:50:29 +0100 Subject: [PATCH 064/179] 76715: Bitstream format cannot be retrieved if you don't have read rights on the file --- .../BitstreamFormatLinkRepository.java | 2 +- .../app/rest/BitstreamRestControllerIT.java | 2 + .../app/rest/BitstreamRestRepositoryIT.java | 235 ++++++++++++++++++ 3 files changed, 238 insertions(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatLinkRepository.java index 830a7f261a..74454161a0 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/BitstreamFormatLinkRepository.java @@ -34,7 +34,7 @@ public class BitstreamFormatLinkRepository extends AbstractDSpaceRestRepository @Autowired BitstreamService bitstreamService; - @PreAuthorize("hasPermission(#bitstreamId, 'BITSTREAM', 'READ')") + @PreAuthorize("hasPermission(#bitstreamId, 'BITSTREAM', 'METADATA_READ')") public BitstreamFormatRest getFormat(@Nullable HttpServletRequest request, UUID bitstreamId, @Nullable Pageable optionalPageable, diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamRestControllerIT.java index 18131444d8..f07aae876f 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamRestControllerIT.java @@ -826,6 +826,7 @@ public class BitstreamRestControllerIT extends AbstractControllerIntegrationTest public void getBitstreamFormatUnauthorized() throws Exception { resourcePolicyService.removePolicies(context, bitstream, READ); + resourcePolicyService.removePolicies(context, bitstream.getBundles().get(0), READ); getClient() .perform(get("/api/core/bitstreams/" + bitstream.getID() + "/format")) @@ -836,6 +837,7 @@ public class BitstreamRestControllerIT extends AbstractControllerIntegrationTest public void getBitstreamFormatForbidden() throws Exception { resourcePolicyService.removePolicies(context, bitstream, READ); + resourcePolicyService.removePolicies(context, bitstream.getBundles().get(0), READ); getClient(getAuthToken(eperson.getEmail(), password)) .perform(get("/api/core/bitstreams/" + bitstream.getID() + "/format")) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamRestRepositoryIT.java index 684eceb639..6f2980a69c 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamRestRepositoryIT.java @@ -37,10 +37,12 @@ import org.dspace.builder.CommunityBuilder; import org.dspace.builder.ItemBuilder; import org.dspace.builder.ResourcePolicyBuilder; import org.dspace.content.Bitstream; +import org.dspace.content.BitstreamFormat; import org.dspace.content.Bundle; import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.Item; +import org.dspace.content.service.BitstreamFormatService; import org.dspace.content.service.BitstreamService; import org.dspace.core.Constants; import org.dspace.eperson.EPerson; @@ -56,6 +58,9 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest @Autowired private ResourcePolicyService resourcePolicyService; + @Autowired + private BitstreamFormatService bitstreamFormatService; + @Test public void findAllTest() throws Exception { //We turn off the authorization system in order to create the structure as defined below @@ -289,6 +294,52 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest ; } + @Test + public void findOneBitstreamFormatTest_EmbargoedBitstream_Anon() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .build(); + + // a public item with an embargoed bitstream + String bitstreamContent = "Embargoed!"; + + BitstreamFormat bitstreamFormat = bitstreamFormatService.findByMIMEType(context, "text/plain"); + + Item publicItem1; + Bitstream bitstream; + try (InputStream is = IOUtils.toInputStream(bitstreamContent, org.apache.commons.lang3.CharEncoding.UTF_8)) { + + publicItem1 = ItemBuilder.createItem(context, col1) + .withTitle("Public item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .build(); + + bitstream = BitstreamBuilder + .createBitstream(context, publicItem1, is) + .withName("Test Embargoed Bitstream") + .withDescription("This bitstream is embargoed") + .withMimeType(bitstreamFormat.getMIMEType()) + .withEmbargoPeriod("3 months") + .build(); + } + context.restoreAuthSystemState(); + + // Bitstream format should still be accessible by anonymous request + getClient().perform(get("/api/core/bitstreams/" + bitstream.getID() + "/format")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", BitstreamFormatMatcher.matchBitstreamFormat( + bitstreamFormat.getID(), bitstreamFormat.getMIMEType(), bitstreamFormat.getDescription()))) + .andExpect(jsonPath("$", HalMatcher.matchNoEmbeds())) + ; + } + @Test public void findOneBitstreamTest_NoReadPolicyOnBitstream_Anon() throws Exception { //We turn off the authorization system in order to create the structure as defined below @@ -346,6 +397,58 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest ; } + @Test + public void findOneBitstreamFormatTest_NoReadPolicyOnBitstream_Anon() throws Exception { + //We turn off the authorization system in order to create the structure as defined below + context.turnOffAuthorisationSystem(); + + //** GIVEN ** + //1. A community-collection structure with one parent community with sub-community and one collection. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build(); + + //2. One public items that is readable by Anonymous + Item publicItem1 = ItemBuilder.createItem(context, col1) + .withTitle("Test") + .withIssueDate("2010-10-17") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry") + .build(); + + String bitstreamContent = "ThisIsSomeDummyText"; + + BitstreamFormat bitstreamFormat = bitstreamFormatService.findByMIMEType(context, "text/plain"); + + //Add a bitstream to an item + Bitstream bitstream = null; + try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { + bitstream = BitstreamBuilder. + createBitstream(context, publicItem1, is) + .withName("Bitstream") + .withDescription("Description") + .withMimeType(bitstreamFormat.getMIMEType()) + .build(); + } + + // Remove all READ policies on bitstream + resourcePolicyService.removePolicies(context, bitstream, Constants.READ); + + context.restoreAuthSystemState(); + + // Bitstream format should still be accessible by anonymous request + getClient().perform(get("/api/core/bitstreams/" + bitstream.getID() + "/format")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", BitstreamFormatMatcher.matchBitstreamFormat( + bitstreamFormat.getID(), bitstreamFormat.getMIMEType(), bitstreamFormat.getDescription()))) + .andExpect(jsonPath("$", HalMatcher.matchNoEmbeds())) + ; + } + @Test public void findOneBitstreamTest_EmbargoedBitstream_NoREADRightsOnBundle() throws Exception { context.turnOffAuthorisationSystem(); @@ -404,6 +507,69 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest ; } + @Test + public void findOneBitstreamFormatTest_EmbargoedBitstream_NoREADRightsOnBundle() throws Exception { + context.turnOffAuthorisationSystem(); + context.setCurrentUser(eperson); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .build(); + + // a public item with an embargoed bitstream + String bitstreamContent = "Embargoed!"; + + BitstreamFormat bitstreamFormat = bitstreamFormatService.findByMIMEType(context, "text/plain"); + + Item publicItem1; + Bitstream bitstream; + try (InputStream is = IOUtils.toInputStream(bitstreamContent, org.apache.commons.lang3.CharEncoding.UTF_8)) { + + publicItem1 = ItemBuilder.createItem(context, col1) + .withTitle("Public item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .build(); + + bitstream = BitstreamBuilder + .createBitstream(context, publicItem1, is) + .withName("Test Embargoed Bitstream") + .withDescription("This bitstream is embargoed") + .withMimeType(bitstreamFormat.getMIMEType()) + .withEmbargoPeriod("3 months") + .build(); + } + + // Remove read policies on bundle of bitstream + resourcePolicyService.removePolicies(context, bitstream.getBundles().get(0), Constants.READ); + + context.restoreAuthSystemState(); + + // Bitstream format should not be accessible by anonymous request + getClient().perform(get("/api/core/bitstreams/" + bitstream.getID() + "/format")) + .andExpect(status().isUnauthorized()) + ; + + // Bitstream format should not be accessible by submitter + String submitterToken = getAuthToken(context.getCurrentUser().getEmail(), password); + getClient(submitterToken).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/format")) + .andExpect(status().isForbidden()) + ; + + // Bitstream format should be accessible by admin + String adminToken = getAuthToken(admin.getEmail(), password); + getClient(adminToken).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/format")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", BitstreamFormatMatcher.matchBitstreamFormat( + bitstreamFormat.getID(), bitstreamFormat.getMIMEType(), bitstreamFormat.getDescription()))) + .andExpect(jsonPath("$", HalMatcher.matchNoEmbeds())) + ; + } + @Test public void findOneBitstreamTest_EmbargoedBitstream_ePersonREADRightsOnBundle() throws Exception { context.turnOffAuthorisationSystem(); @@ -465,6 +631,75 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest ; } + @Test + public void findOneBitstreamFormatTest_EmbargoedBitstream_ePersonREADRightsOnBundle() throws Exception { + context.turnOffAuthorisationSystem(); + context.setCurrentUser(eperson); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .build(); + + // a public item with an embargoed bitstream + String bitstreamContent = "Embargoed!"; + + BitstreamFormat bitstreamFormat = bitstreamFormatService.findByMIMEType(context, "text/plain"); + + Item publicItem1; + Bitstream bitstream; + try (InputStream is = IOUtils.toInputStream(bitstreamContent, org.apache.commons.lang3.CharEncoding.UTF_8)) { + + publicItem1 = ItemBuilder.createItem(context, col1) + .withTitle("Public item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .build(); + + bitstream = BitstreamBuilder + .createBitstream(context, publicItem1, is) + .withName("Test Embargoed Bitstream") + .withDescription("This bitstream is embargoed") + .withMimeType(bitstreamFormat.getMIMEType()) + .withEmbargoPeriod("3 months") + .build(); + } + + // Replace anon read policy on bundle of bitstream with ePerson READ policy + resourcePolicyService.removePolicies(context, bitstream.getBundles().get(0), Constants.READ); + ResourcePolicyBuilder.createResourcePolicy(context).withUser(eperson) + .withAction(Constants.READ) + .withDspaceObject(bitstream.getBundles().get(0)).build(); + + context.restoreAuthSystemState(); + + // Bitstream format should not be accessible by anonymous request + getClient().perform(get("/api/core/bitstreams/" + bitstream.getID() + "/format")) + .andExpect(status().isUnauthorized()) + ; + + // Bitstream format should be accessible by eperson + String submitterToken = getAuthToken(context.getCurrentUser().getEmail(), password); + getClient(submitterToken).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/format")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", BitstreamFormatMatcher.matchBitstreamFormat( + bitstreamFormat.getID(), bitstreamFormat.getMIMEType(), bitstreamFormat.getDescription()))) + .andExpect(jsonPath("$", HalMatcher.matchNoEmbeds())) + ; + + // Bitstream format should be accessible by admin + String adminToken = getAuthToken(admin.getEmail(), password); + getClient(adminToken).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/format")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", BitstreamFormatMatcher.matchBitstreamFormat( + bitstreamFormat.getID(), bitstreamFormat.getMIMEType(), bitstreamFormat.getDescription()))) + .andExpect(jsonPath("$", HalMatcher.matchNoEmbeds())) + ; + } + @Test public void findOneBitstreamTest_EmbargoedBitstream_NoREADRightsOnItem() throws Exception { context.turnOffAuthorisationSystem(); From 510ee70807768b742316462b112d4d642803b9bc Mon Sep 17 00:00:00 2001 From: Peter Nijs Date: Mon, 8 Feb 2021 12:41:56 +0100 Subject: [PATCH 065/179] 75924: Fixed style issues in GenerateSitemaps --- .../org/dspace/app/sitemap/GenerateSitemaps.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/sitemap/GenerateSitemaps.java b/dspace-api/src/main/java/org/dspace/app/sitemap/GenerateSitemaps.java index d0fe7d184c..5057477e31 100644 --- a/dspace-api/src/main/java/org/dspace/app/sitemap/GenerateSitemaps.java +++ b/dspace-api/src/main/java/org/dspace/app/sitemap/GenerateSitemaps.java @@ -254,10 +254,14 @@ public class GenerateSitemaps { String url; if (CollectionUtils.isNotEmpty(discoverResult.getIndexableObjects()) - && CollectionUtils.isNotEmpty(discoverResult.getSearchDocument(discoverResult.getIndexableObjects().get(0)).get(0).getSearchFieldValues("entityType")) - && StringUtils.isNotBlank(discoverResult.getSearchDocument(discoverResult.getIndexableObjects().get(0)).get(0).getSearchFieldValues("entityType").get(0))) - { - url = uiURLStem + "/entities/" + StringUtils.lowerCase(discoverResult.getSearchDocument(discoverResult.getIndexableObjects().get(0)).get(0).getSearchFieldValues("entityType").get(0)) + "/" + i.getID(); + && CollectionUtils.isNotEmpty(discoverResult.getSearchDocument( + discoverResult.getIndexableObjects().get(0)).get(0).getSearchFieldValues("entityType")) + && StringUtils.isNotBlank(discoverResult.getSearchDocument( + discoverResult.getIndexableObjects().get(0)).get(0).getSearchFieldValues("entityType").get(0)) + ) { + url = uiURLStem + "/entities/" + StringUtils.lowerCase(discoverResult.getSearchDocument( + discoverResult.getIndexableObjects().get(0)) + .get(0).getSearchFieldValues("entityType").get(0)) + "/" + i.getID(); } else { url = uiURLStem + "/items/" + i.getID(); } From 4f821ca417673067673c31160232bc53695611a0 Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Wed, 10 Feb 2021 14:42:50 +0100 Subject: [PATCH 066/179] Test hibernate level 1 cache --- .../dao/impl/MetadataFieldDAOImpl.java | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/content/dao/impl/MetadataFieldDAOImpl.java b/dspace-api/src/main/java/org/dspace/content/dao/impl/MetadataFieldDAOImpl.java index c53ea0c9a7..907b2892a9 100644 --- a/dspace-api/src/main/java/org/dspace/content/dao/impl/MetadataFieldDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/dao/impl/MetadataFieldDAOImpl.java @@ -8,8 +8,10 @@ package org.dspace.content.dao.impl; import java.sql.SQLException; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import javax.persistence.Query; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; @@ -17,6 +19,7 @@ import javax.persistence.criteria.Join; import javax.persistence.criteria.Root; import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.Logger; import org.dspace.content.MetadataField; import org.dspace.content.MetadataField_; import org.dspace.content.MetadataSchema; @@ -24,6 +27,7 @@ import org.dspace.content.MetadataSchema_; import org.dspace.content.dao.MetadataFieldDAO; import org.dspace.core.AbstractHibernateDAO; import org.dspace.core.Context; +import org.hibernate.Session; /** * Hibernate implementation of the Database Access Object interface class for the MetadataField object. @@ -33,6 +37,13 @@ import org.dspace.core.Context; * @author kevinvandevelde at atmire.com */ public class MetadataFieldDAOImpl extends AbstractHibernateDAO implements MetadataFieldDAO { + /** + * log4j logger + */ + private static Logger log = org.apache.logging.log4j.LogManager.getLogger(MetadataFieldDAOImpl.class); + + private static Map cachedFields = new HashMap(); + protected MetadataFieldDAOImpl() { super(); } @@ -79,6 +90,30 @@ public class MetadataFieldDAOImpl extends AbstractHibernateDAO im @Override public MetadataField findByElement(Context context, String metadataSchema, String element, String qualifier) throws SQLException { + String key = metadataSchema + "." + element + "." + qualifier; + if (cachedFields.containsKey(key)) { + Session session = getHibernateSession(context); + MetadataField metadataField = null; + try { + metadataField = session.load(MetadataField.class, cachedFields.get(key)); + } catch (Throwable e) { + log.error("Failed to load metadata field " + key + " using ID " + cachedFields.get(key)); + } + try { + if (metadataField != null && + (metadataField.getMetadataSchema().getName() + "." + metadataField.getElement() + + "." + metadataField.getQualifier()).equals(key)) { + return metadataField; + } else { + cachedFields.remove(key); + } + } catch (Throwable e) { + log.error("Failed to verify consistence of metadata field " + key + + " using ID " + cachedFields.get(key)); + cachedFields.clear(); + } + } + Query query; if (StringUtils.isNotBlank(qualifier)) { @@ -103,7 +138,11 @@ public class MetadataFieldDAOImpl extends AbstractHibernateDAO im } query.setHint("org.hibernate.cacheable", Boolean.TRUE); - return singleResult(query); + MetadataField metadataField = singleResult(query); + if (metadataField != null) { + cachedFields.put(key, metadataField.getID()); + } + return metadataField; } @Override From 7d419b5efa99997011b1880404f44109e64792d3 Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Thu, 11 Feb 2021 11:03:39 +0100 Subject: [PATCH 067/179] Feedback on the PR --- .../rest/WorkspaceItemRestRepositoryIT.java | 38 +------------------ 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java index 8dfbc8d6bd..2584f5750f 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java @@ -4640,42 +4640,6 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration .andExpect(jsonPath("$.sections.upload.files[0].accessConditions", empty())); } - // The REST endpoint doesn't seem to support uploading a bitstream with the access conditions - @Test - @Ignore - public void uploadBitstreamWithAccessConditionOpenAccess() throws Exception { - context.turnOffAuthorisationSystem(); - Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); - Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build(); - WorkspaceItem wItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection).build(); - context.restoreAuthSystemState(); - - // prepare dummy bitstream - InputStream pdf = getClass().getResourceAsStream("simple-article.pdf"); - final MockMultipartFile pdfFile = new MockMultipartFile("file", "/local/path/simple-article.pdf", - "application/pdf", pdf); - - // auth - String authToken = getAuthToken(eperson.getEmail(), password); - - // upload file and verify response - getClient(authToken) - .perform(fileUpload("/api/submission/workspaceitems/" + wItem.getID()) - .file(pdfFile) - // TODO: send access conditions with request - ) - .andExpect(status().isCreated()) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))); - - // verify that access conditions have been persisted - getClient(authToken) - .perform(get("/api/submission/workspaceitems/" + wItem.getID())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.sections.upload.files[0].accessConditions[0].name", is("openaccess"))); - } - - // TODO: all cases in 74236 that start with "upload a new bitstream" - @Test public void patchBitstreamWithAccessConditionOpenAccess() throws Exception { context.turnOffAuthorisationSystem(); @@ -4950,7 +4914,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration } @Test - public void patchBitstreamWithAccessConditionLease() throws Exception { + public void patchBitstreamWithAccessConditionLeaseMissingDate() throws Exception { context.turnOffAuthorisationSystem(); Community community = CommunityBuilder.createCommunity(context).withName("Com").build(); Collection collection = CollectionBuilder.createCollection(context, community).withName("Col").build(); From c592b6b4e4fbf0287764fd2e0a45cc6790a033f0 Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Thu, 11 Feb 2021 11:15:31 +0100 Subject: [PATCH 068/179] Feedback on the PR --- .../org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java index 2584f5750f..65cdf77c2a 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java @@ -67,7 +67,6 @@ import org.dspace.eperson.factory.EPersonServiceFactory; import org.dspace.services.ConfigurationService; import org.hamcrest.Matchers; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockMultipartFile; @@ -3282,7 +3281,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration } @Test - public void patchUploadRemoveAccessConditionTest() throws Exception { + public void patchUploadAddAndRemoveAccessConditionTest() throws Exception { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context) From 80f76b4e0a46144fda5b396d77ef7d212f30c5d3 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 11 Feb 2021 14:56:11 -0600 Subject: [PATCH 069/179] Fix ability to run partial migrations by disabling callbacks and reindex --- .../dspace/storage/rdbms/DatabaseUtils.java | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseUtils.java b/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseUtils.java index 5f8e72a535..98777c654b 100644 --- a/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseUtils.java +++ b/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseUtils.java @@ -201,14 +201,11 @@ public class DatabaseUtils { "You've specified to migrate your database ONLY to version " + migrationVersion + " " + "..."); System.out.println( - "\nWARNING: It is highly likely you will see errors in your logs when the Metadata"); - System.out.println( - "or Bitstream Format Registry auto-update. This is because you are attempting to"); - System.out.println( - "use an OLD version " + migrationVersion + " Database with a newer DSpace API. NEVER " + - "do this in a"); - System.out.println( - "PRODUCTION scenario. The resulting old DB is only useful for migration testing.\n"); + "\nWARNING: In this mode, we DISABLE all callbacks, which means that you will need " + + "to manually update registries and manually run a reindex. This is because you " + + "are attempting to use an OLD version (" + migrationVersion + ") Database with " + + "a newer DSpace API. NEVER do this in a PRODUCTION scenario. The resulting " + + "database is only useful for migration testing.\n"); System.out.print( "Are you SURE you only want to migrate your database to version " + migrationVersion @@ -647,7 +644,7 @@ public class DatabaseUtils { * @param datasource DataSource object (retrieved from DatabaseManager()) * @param connection Database connection * @param targetVersion If specified, only migrate the database to a particular *version* of DSpace. This is - * mostly just useful for testing. + * just useful for testing migrations, and should NOT be used in Production. * If null, the database is migrated to the latest version. * @param outOfOrder If true, Flyway will run any lower version migrations that were previously "ignored". * If false, Flyway will only run new migrations with a higher version number. @@ -661,6 +658,10 @@ public class DatabaseUtils { throw new SQLException("The datasource is a null reference -- cannot continue."); } + // Whether to reindex all content in Solr after successfully updating database + boolean reindexAfterUpdate = DSpaceServicesFactory.getInstance().getConfigurationService() + .getBooleanProperty("discovery.autoReindex", true); + try { // Setup Flyway API against our database FluentConfiguration flywayConfiguration = setupFlyway(datasource); @@ -671,8 +672,14 @@ public class DatabaseUtils { // If a target version was specified, tell Flyway to ONLY migrate to that version // (i.e. all later migrations are left as "pending"). By default we always migrate to latest version. + // This mode is only useful for testing migrations & should NEVER be used in Production. if (!StringUtils.isBlank(targetVersion)) { flywayConfiguration.target(targetVersion); + // Disable all callbacks. Most callbacks use the Context object which triggers a full database update, + // bypassing this target version. + flywayConfiguration.callbacks(new Callback[]{}); + // Also disable reindex after update for this migration mode (as reindex also uses Context object) + reindexAfterUpdate = false; } // Initialized Flyway object (will be created by flywayConfiguration.load() below) @@ -722,7 +729,7 @@ public class DatabaseUtils { flyway.migrate(); // Flag that Discovery will need reindexing, since database was updated - setReindexDiscovery(true); + setReindexDiscovery(reindexAfterUpdate); } else { log.info("DSpace database schema is up to date"); } From 0997b9645bee85137af021e4bf20a5c8fa00c14d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Fri, 12 Feb 2021 19:49:23 +0000 Subject: [PATCH 070/179] comments improvement and fix dc.right processing --- .../crosswalks/oai/metadataFormats/oai_openaire.xsl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl b/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl index 613a737b02..ab659d3591 100644 --- a/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl +++ b/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl @@ -525,8 +525,8 @@ - - + + @@ -537,9 +537,9 @@ - - - + From 66cdc0134931a05036d1bc055718940f81e60199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gra=C3=A7a?= Date: Fri, 12 Feb 2021 22:44:39 +0000 Subject: [PATCH 071/179] deal with dc:identifier.* having multiple languages --- .../oai/metadataFormats/oai_openaire.xsl | 118 ++++++++++-------- 1 file changed, 65 insertions(+), 53 deletions(-) diff --git a/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl b/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl index ddda1c2fdb..7f585495d0 100644 --- a/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl +++ b/dspace/config/crosswalks/oai/metadataFormats/oai_openaire.xsl @@ -5,9 +5,9 @@ detailed in the LICENSE and NOTICE files at the root of the source tree and available online at - Developed by Paulo Graça - - > https://www.openaire.eu/schema/repo-lit/4.0/openaire.xsd + Developed by Paulo Graça + + > https://www.openaire.eu/schema/repo-lit/4.0/openaire.xsd --> - - - + - - - - - + + + + + + + - + - - - - - + + + + + + + - + - - - - - + + + + + + + - + - - - - - + + + + + + + - + - - - - - + + + + + + + - + - - - - - - + + + + + + + + - + - - - - - + + + + + + + - - + + From ef58d629b0daf4f12ffb903d509462a301cf99c4 Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Fri, 19 Feb 2021 12:30:55 +0100 Subject: [PATCH 072/179] Testing metadata field performance --- .../content/MetadataFieldPerformanceTest.java | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 dspace-api/src/test/java/org/dspace/content/MetadataFieldPerformanceTest.java diff --git a/dspace-api/src/test/java/org/dspace/content/MetadataFieldPerformanceTest.java b/dspace-api/src/test/java/org/dspace/content/MetadataFieldPerformanceTest.java new file mode 100644 index 0000000000..b8e1a0081e --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/content/MetadataFieldPerformanceTest.java @@ -0,0 +1,98 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.content; + +import java.sql.SQLException; + +import org.dspace.AbstractUnitTest; +import org.dspace.authorize.AuthorizeException; +import org.dspace.content.factory.ContentServiceFactory; +import org.dspace.content.service.CollectionService; +import org.dspace.content.service.CommunityService; +import org.dspace.content.service.MetadataFieldService; +import org.junit.Assert; +import org.junit.Test; + +/** + * Unit Tests for Performance of class MetadataField + * + * @author ben @ atmire . com + */ +public class MetadataFieldPerformanceTest extends AbstractUnitTest { + + private final MetadataFieldService metadataFieldService = + ContentServiceFactory.getInstance().getMetadataFieldService(); + private final CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService(); + private final CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService(); + + @Test + public void testManyQueries() throws SQLException { + + long startTime = System.currentTimeMillis(); + + int amount = 50000; + for (int i = 0; i < amount; i++) { + metadataFieldService.findByElement(context, "dc", "description", null); + } + long endTime = System.currentTimeMillis(); + + long duration = (endTime - startTime); + + double maxDurationPerCall = 0.02; + double maxDuration = maxDurationPerCall * amount; + //Duration is 0.05798 without performance improvements + Assert.assertTrue("Duration (" + duration + ") should be smaller than " + maxDuration + + " for " + amount + " tests." + + " Max of " + maxDurationPerCall + " ms per operation exceeded: " + + (((double) (duration)) / amount) + " ms.", duration < maxDuration); + } + + @Test + public void testManyMetadataAdds() throws SQLException, AuthorizeException { + context.turnOffAuthorisationSystem(); + Community owningCommunity = communityService.create(null, context); + Collection collection = collectionService.create(context, owningCommunity); + //we need to commit the changes so we don't block the table for testing + context.restoreAuthSystemState(); + + long startTime = System.currentTimeMillis(); + + int amount = 5000; + for (int i = 0; i < amount; i++) { + collectionService.addMetadata(context, collection, + "dc", "description", null, null, "Test " + i); + collectionService.clearMetadata(context, collection, + "dc", "description", null, null); + } + long endTime = System.currentTimeMillis(); + + long duration = (endTime - startTime); + + double maxDurationPerCall = 1; + double maxDuration = maxDurationPerCall * amount; + //Duration is 1.542 without performance improvements + Assert.assertTrue("Duration (" + duration + ") should be smaller than " + maxDuration + + " for " + amount + " tests." + + " Max of " + maxDurationPerCall + " ms per operation exceeded: " + + (((double) (duration)) / amount) + " ms.", duration < maxDuration); + + context.turnOffAuthorisationSystem(); + // Delete community & collection created in init() + try { + collectionService.delete(context, collection); + } catch (Exception e) { + // ignore + } + try { + communityService.delete(context, owningCommunity); + } catch (Exception e) { + // ignore + } + context.restoreAuthSystemState(); + } +} From 11efc35cae24f7667536a190bb70d215a229a4a3 Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Fri, 19 Feb 2021 13:08:10 +0100 Subject: [PATCH 073/179] Testing metadata field performance --- .../java/org/dspace/content/MetadataFieldPerformanceTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dspace-api/src/test/java/org/dspace/content/MetadataFieldPerformanceTest.java b/dspace-api/src/test/java/org/dspace/content/MetadataFieldPerformanceTest.java index b8e1a0081e..5cbf343203 100644 --- a/dspace-api/src/test/java/org/dspace/content/MetadataFieldPerformanceTest.java +++ b/dspace-api/src/test/java/org/dspace/content/MetadataFieldPerformanceTest.java @@ -46,6 +46,7 @@ public class MetadataFieldPerformanceTest extends AbstractUnitTest { double maxDurationPerCall = 0.02; double maxDuration = maxDurationPerCall * amount; //Duration is 0.05798 without performance improvements + //Duration is 0.0022 with performance improvements Assert.assertTrue("Duration (" + duration + ") should be smaller than " + maxDuration + " for " + amount + " tests." + " Max of " + maxDurationPerCall + " ms per operation exceeded: " + @@ -76,6 +77,7 @@ public class MetadataFieldPerformanceTest extends AbstractUnitTest { double maxDurationPerCall = 1; double maxDuration = maxDurationPerCall * amount; //Duration is 1.542 without performance improvements + //Duration is 0.0538 with performance improvements Assert.assertTrue("Duration (" + duration + ") should be smaller than " + maxDuration + " for " + amount + " tests." + " Max of " + maxDurationPerCall + " ms per operation exceeded: " + From 73f22a00f700d7da532bfd91cd0cc8cf6168cd5c Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Fri, 19 Feb 2021 17:05:18 +0100 Subject: [PATCH 074/179] Testing metadata field performance --- .../java/org/dspace/content/MetadataFieldPerformanceTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/content/MetadataFieldPerformanceTest.java b/dspace-api/src/test/java/org/dspace/content/MetadataFieldPerformanceTest.java index 5cbf343203..d9b216f638 100644 --- a/dspace-api/src/test/java/org/dspace/content/MetadataFieldPerformanceTest.java +++ b/dspace-api/src/test/java/org/dspace/content/MetadataFieldPerformanceTest.java @@ -43,7 +43,7 @@ public class MetadataFieldPerformanceTest extends AbstractUnitTest { long duration = (endTime - startTime); - double maxDurationPerCall = 0.02; + double maxDurationPerCall = 0.01; double maxDuration = maxDurationPerCall * amount; //Duration is 0.05798 without performance improvements //Duration is 0.0022 with performance improvements @@ -74,7 +74,7 @@ public class MetadataFieldPerformanceTest extends AbstractUnitTest { long duration = (endTime - startTime); - double maxDurationPerCall = 1; + double maxDurationPerCall = .3; double maxDuration = maxDurationPerCall * amount; //Duration is 1.542 without performance improvements //Duration is 0.0538 with performance improvements From b44fdd2de43a4cd794a812c1eefb47d19b56a465 Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Fri, 19 Feb 2021 17:48:01 +0100 Subject: [PATCH 075/179] JavaDocs --- .../org/dspace/content/dao/impl/MetadataFieldDAOImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/content/dao/impl/MetadataFieldDAOImpl.java b/dspace-api/src/main/java/org/dspace/content/dao/impl/MetadataFieldDAOImpl.java index 907b2892a9..e64aaa4dd2 100644 --- a/dspace-api/src/main/java/org/dspace/content/dao/impl/MetadataFieldDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/dao/impl/MetadataFieldDAOImpl.java @@ -42,6 +42,10 @@ public class MetadataFieldDAOImpl extends AbstractHibernateDAO im */ private static Logger log = org.apache.logging.log4j.LogManager.getLogger(MetadataFieldDAOImpl.class); + /** + * Cache for improvement the performance of searching metadata fields + * This cache only stores IDs, the actual MetadataField is retrieved from hibernate + */ private static Map cachedFields = new HashMap(); protected MetadataFieldDAOImpl() { From 941da71713bceb7510fa37f836b53d3825e39dfd Mon Sep 17 00:00:00 2001 From: Peter Nijs Date: Mon, 22 Feb 2021 10:09:04 +0100 Subject: [PATCH 076/179] 77166: Manual master merge fixes --- .../dspace/app/rest/ItemRestRepositoryIT.java | 75 ++++++++++++------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java index 35222e9545..233cc4e7db 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java @@ -2958,16 +2958,26 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { .andExpect(status().isOk()) .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) .andExpect(jsonPath("$._embedded.bundles._embedded.bundles",Matchers.containsInAnyOrder( - BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), bundle0.getType()), - BundleMatcher.matchProperties(bundle1.getName(), bundle1.getID(), bundle1.getHandle(), bundle1.getType()), - BundleMatcher.matchProperties(bundle2.getName(), bundle2.getID(), bundle2.getHandle(), bundle2.getType()), - BundleMatcher.matchProperties(bundle3.getName(), bundle3.getID(), bundle3.getHandle(), bundle3.getType()), - BundleMatcher.matchProperties(bundle4.getName(), bundle4.getID(), bundle4.getHandle(), bundle4.getType()), - BundleMatcher.matchProperties(bundle5.getName(), bundle5.getID(), bundle5.getHandle(), bundle5.getType()), - BundleMatcher.matchProperties(bundle6.getName(), bundle6.getID(), bundle6.getHandle(), bundle6.getType()), - BundleMatcher.matchProperties(bundle7.getName(), bundle7.getID(), bundle7.getHandle(), bundle7.getType()), - BundleMatcher.matchProperties(bundle8.getName(), bundle8.getID(), bundle8.getHandle(), bundle8.getType()), - BundleMatcher.matchProperties(bundle9.getName(), bundle9.getID(), bundle9.getHandle(), bundle9.getType()) + BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), + bundle0.getType()), + BundleMatcher.matchProperties(bundle1.getName(), bundle1.getID(), bundle1.getHandle(), + bundle1.getType()), + BundleMatcher.matchProperties(bundle2.getName(), bundle2.getID(), bundle2.getHandle(), + bundle2.getType()), + BundleMatcher.matchProperties(bundle3.getName(), bundle3.getID(), bundle3.getHandle(), + bundle3.getType()), + BundleMatcher.matchProperties(bundle4.getName(), bundle4.getID(), bundle4.getHandle(), + bundle4.getType()), + BundleMatcher.matchProperties(bundle5.getName(), bundle5.getID(), bundle5.getHandle(), + bundle5.getType()), + BundleMatcher.matchProperties(bundle6.getName(), bundle6.getID(), bundle6.getHandle(), + bundle6.getType()), + BundleMatcher.matchProperties(bundle7.getName(), bundle7.getID(), bundle7.getHandle(), + bundle7.getType()), + BundleMatcher.matchProperties(bundle8.getName(), bundle8.getID(), bundle8.getHandle(), + bundle8.getType()), + BundleMatcher.matchProperties(bundle9.getName(), bundle9.getID(), bundle9.getHandle(), + bundle9.getType()) ))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items/" + item.getID()))) .andExpect(jsonPath("$._embedded.bundles.page.size", is(20))) @@ -3007,11 +3017,16 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { .andExpect(status().isOk()) .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) .andExpect(jsonPath("$._embedded.bundles._embedded.bundles",Matchers.containsInAnyOrder( - BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), bundle0.getType()), - BundleMatcher.matchProperties(bundle1.getName(), bundle1.getID(), bundle1.getHandle(), bundle1.getType()), - BundleMatcher.matchProperties(bundle2.getName(), bundle2.getID(), bundle2.getHandle(), bundle2.getType()), - BundleMatcher.matchProperties(bundle3.getName(), bundle3.getID(), bundle3.getHandle(), bundle3.getType()), - BundleMatcher.matchProperties(bundle4.getName(), bundle4.getID(), bundle4.getHandle(), bundle4.getType()) + BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), + bundle0.getType()), + BundleMatcher.matchProperties(bundle1.getName(), bundle1.getID(), bundle1.getHandle(), + bundle1.getType()), + BundleMatcher.matchProperties(bundle2.getName(), bundle2.getID(), bundle2.getHandle(), + bundle2.getType()), + BundleMatcher.matchProperties(bundle3.getName(), bundle3.getID(), bundle3.getHandle(), + bundle3.getType()), + BundleMatcher.matchProperties(bundle4.getName(), bundle4.getID(), bundle4.getHandle(), + bundle4.getType()) ))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items/" + item.getID()))) .andExpect(jsonPath("$._embedded.bundles.page.size", is(5))) @@ -3052,16 +3067,26 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { .andExpect(status().isOk()) .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) .andExpect(jsonPath("$._embedded.bundles._embedded.bundles",Matchers.containsInAnyOrder( - BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), bundle0.getType()), - BundleMatcher.matchProperties(bundle1.getName(), bundle1.getID(), bundle1.getHandle(), bundle1.getType()), - BundleMatcher.matchProperties(bundle2.getName(), bundle2.getID(), bundle2.getHandle(), bundle2.getType()), - BundleMatcher.matchProperties(bundle3.getName(), bundle3.getID(), bundle3.getHandle(), bundle3.getType()), - BundleMatcher.matchProperties(bundle4.getName(), bundle4.getID(), bundle4.getHandle(), bundle4.getType()), - BundleMatcher.matchProperties(bundle5.getName(), bundle5.getID(), bundle5.getHandle(), bundle5.getType()), - BundleMatcher.matchProperties(bundle6.getName(), bundle6.getID(), bundle6.getHandle(), bundle6.getType()), - BundleMatcher.matchProperties(bundle7.getName(), bundle7.getID(), bundle7.getHandle(), bundle7.getType()), - BundleMatcher.matchProperties(bundle8.getName(), bundle8.getID(), bundle8.getHandle(), bundle8.getType()), - BundleMatcher.matchProperties(bundle9.getName(), bundle9.getID(), bundle9.getHandle(), bundle9.getType()) + BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), + bundle0.getType()), + BundleMatcher.matchProperties(bundle1.getName(), bundle1.getID(), bundle1.getHandle(), + bundle1.getType()), + BundleMatcher.matchProperties(bundle2.getName(), bundle2.getID(), bundle2.getHandle(), + bundle2.getType()), + BundleMatcher.matchProperties(bundle3.getName(), bundle3.getID(), bundle3.getHandle(), + bundle3.getType()), + BundleMatcher.matchProperties(bundle4.getName(), bundle4.getID(), bundle4.getHandle(), + bundle4.getType()), + BundleMatcher.matchProperties(bundle5.getName(), bundle5.getID(), bundle5.getHandle(), + bundle5.getType()), + BundleMatcher.matchProperties(bundle6.getName(), bundle6.getID(), bundle6.getHandle(), + bundle6.getType()), + BundleMatcher.matchProperties(bundle7.getName(), bundle7.getID(), bundle7.getHandle(), + bundle7.getType()), + BundleMatcher.matchProperties(bundle8.getName(), bundle8.getID(), bundle8.getHandle(), + bundle8.getType()), + BundleMatcher.matchProperties(bundle9.getName(), bundle9.getID(), bundle9.getHandle(), + bundle9.getType()) ))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items/" + item.getID()))) .andExpect(jsonPath("$._embedded.bundles.page.size", is(20))) From 79830641e2f9927dd1fe4b2697af34962f34659e Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Tue, 23 Feb 2021 12:11:37 +0100 Subject: [PATCH 077/179] Marking metadata as updated after adding a metadata value --- .../main/java/org/dspace/content/DSpaceObjectServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/dspace-api/src/main/java/org/dspace/content/DSpaceObjectServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/DSpaceObjectServiceImpl.java index 79d7f3690e..13e4d83fa0 100644 --- a/dspace-api/src/main/java/org/dspace/content/DSpaceObjectServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/DSpaceObjectServiceImpl.java @@ -305,6 +305,7 @@ public abstract class DSpaceObjectServiceImpl implements // metadataValueService.update(context, metadataValue); dso.addDetails(metadataField.toString()); } + setMetadataModified(dso); return newMetadata; } From 5715d7d377489b22c295e48512bcaad8dc28eea9 Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Tue, 23 Feb 2021 12:18:40 +0100 Subject: [PATCH 078/179] Marking metadata as updated after changing the relationship place --- dspace-api/src/main/java/org/dspace/content/Relationship.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/content/Relationship.java b/dspace-api/src/main/java/org/dspace/content/Relationship.java index 3a2aad5bdf..72ffbedff0 100644 --- a/dspace-api/src/main/java/org/dspace/content/Relationship.java +++ b/dspace-api/src/main/java/org/dspace/content/Relationship.java @@ -164,6 +164,7 @@ public class Relationship implements ReloadableEntity { */ public void setLeftPlace(int leftPlace) { this.leftPlace = leftPlace; + leftItem.setMetadataModified(); } /** @@ -180,6 +181,7 @@ public class Relationship implements ReloadableEntity { */ public void setRightPlace(int rightPlace) { this.rightPlace = rightPlace; + rightItem.setMetadataModified(); } /** From ceec8433c84e7cdf62972e11fd18cdff7b690579 Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Tue, 23 Feb 2021 12:45:38 +0100 Subject: [PATCH 079/179] Checkstyle --- .../src/main/java/org/dspace/content/Item.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/content/Item.java b/dspace-api/src/main/java/org/dspace/content/Item.java index 6c07329f12..c9ebf5559d 100644 --- a/dspace-api/src/main/java/org/dspace/content/Item.java +++ b/dspace-api/src/main/java/org/dspace/content/Item.java @@ -13,8 +13,19 @@ import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; -import javax.persistence.*; +import javax.persistence.CascadeType; +import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; import org.apache.log4j.Logger; import org.dspace.content.comparator.NameAscendingComparator; From f5043f15c37d4ecfbc81e8c84c8b27cd700d560e Mon Sep 17 00:00:00 2001 From: Ben Bosman Date: Tue, 23 Feb 2021 13:19:03 +0100 Subject: [PATCH 080/179] The relationship metadata is created Also add checks based on plain metadata only --- .../RelationshipMetadataServiceIT.java | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java b/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java index ab1d8cfc97..798a549f9e 100644 --- a/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java +++ b/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java @@ -14,6 +14,7 @@ import static org.junit.Assert.assertTrue; import java.sql.SQLException; import java.util.List; +import java.util.stream.Collectors; import org.dspace.AbstractIntegrationTestWithDatabase; import org.dspace.authorize.AuthorizeException; @@ -233,12 +234,36 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa public void testDeleteAuthorRelationshipCopyToBothItems() throws Exception { initPublicationAuthor(); context.turnOffAuthorisationSystem(); + //verify the dc.contributor.author virtual metadata + List authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); + assertThat(authorList.size(), equalTo(1)); + + //verify the dc.contributor.author actual metadata + List plainMetadataAuthorList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null && + metadataValue.getMetadataField().getQualifier().equals("author")) + .collect(Collectors.toList()); + assertThat(plainMetadataAuthorList.size(), equalTo(0)); + + //verify there's no relation.isAuthorOfPublication actual metadata + List plainRelationshipMetadataList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication")) + .collect(Collectors.toList()); + assertThat(plainRelationshipMetadataList.size(), equalTo(0)); + //delete the relationship, copying the virtual metadata to actual metadata on the both items relationshipService.delete(context, relationship, true, true); context.restoreAuthSystemState(); //verify the dc.contributor.author actual metadata - List authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); + plainMetadataAuthorList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null && + metadataValue.getMetadataField().getQualifier().equals("author")) + .collect(Collectors.toList()); + assertThat(plainMetadataAuthorList.size(), equalTo(1)); + + //verify the dc.contributor.author actual metadata + authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); assertThat(authorList.size(), equalTo(1)); assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName")); assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc")); @@ -246,10 +271,15 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author")); assertNull(authorList.get(0).getAuthority()); - //verify there's no relation.isAuthorOfPublication actual metadata + //verify there's relation.isAuthorOfPublication actual metadata + plainRelationshipMetadataList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication")) + .collect(Collectors.toList()); + assertThat(plainRelationshipMetadataList.size(), equalTo(1)); + //verify there's relation.isAuthorOfPublication actual metadata List relationshipMetadataList = itemService .getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY); - assertThat(relationshipMetadataList.size(), equalTo(0)); + assertThat(relationshipMetadataList.size(), equalTo(1)); } @Test From 1dc0a815f259193055448c4385a447a2978a6a42 Mon Sep 17 00:00:00 2001 From: Samuel Date: Tue, 23 Feb 2021 19:01:40 +0100 Subject: [PATCH 081/179] Remove Traditional/Basic Workflow from codebase and database - rename Workflow to XmlWorkflow --- .../dspace/app/bulkedit/MetadataImport.java | 10 +- .../app/itemimport/ItemImportServiceImpl.java | 8 +- .../org/dspace/app/util/AuthorizeUtil.java | 4 +- .../authorize/AuthorizeServiceImpl.java | 4 +- .../dspace/content/CollectionServiceImpl.java | 6 +- .../org/dspace/content/ItemServiceImpl.java | 8 +- .../org/dspace/content/WorkspaceItem.java | 4 +- .../content/WorkspaceItemServiceImpl.java | 8 +- .../factory/ContentServiceFactory.java | 4 +- .../packager/AbstractMETSIngester.java | 4 +- .../dspace/content/packager/PackageUtils.java | 6 +- .../content/service/WorkspaceItemService.java | 4 +- .../org/dspace/discovery/SearchUtils.java | 4 +- .../indexobject/IndexableWorkflowItem.java | 8 +- .../indexobject/ItemIndexFactoryImpl.java | 12 +- .../WorkflowItemIndexFactoryImpl.java | 20 +- .../factory/IndexObjectFactoryFactory.java | 4 +- .../factory/WorkflowItemIndexFactory.java | 4 +- .../dspace/eperson/EPersonServiceImpl.java | 23 +- .../java/org/dspace/health/ItemCheck.java | 8 +- .../dspace/identifier/doi/DOIConsumer.java | 4 +- .../main/java/org/dspace/rdf/RDFConsumer.java | 8 +- .../dspace/storage/rdbms/DatabaseUtils.java | 6 +- .../DefaultItemVersionProvider.java | 4 +- .../versioning/VersioningServiceImpl.java | 8 +- .../java/org/dspace/xmlworkflow/Role.java | 4 +- .../WorkflowRequirementsServiceImpl.java | 28 +- .../org/dspace/xmlworkflow/WorkflowUtils.java | 6 +- ...eImpl.java => XmlWorkflowServiceImpl.java} | 70 +-- .../factory/XmlWorkflowServiceFactory.java} | 21 +- .../XmlWorkflowServiceFactoryImpl.java} | 21 +- .../migration/RestartWorkflow.java | 14 +- .../service/WorkflowRequirementsService.java | 10 +- .../service/XmlWorkflowService.java} | 46 +- .../org/dspace/xmlworkflow/state/Step.java | 6 +- .../dspace/xmlworkflow/state/Workflow.java | 4 +- .../xmlworkflow/state/actions/Action.java | 10 +- .../AcceptEditRejectAction.java | 22 +- .../processingaction/FinalEditAction.java | 14 +- .../processingaction/ProcessingAction.java | 4 +- .../processingaction/ReviewAction.java | 22 +- .../ScoreEvaluationAction.java | 10 +- .../processingaction/ScoreReviewAction.java | 6 +- .../SelectReviewerAction.java | 6 +- .../SingleUserReviewAction.java | 22 +- .../actions/userassignment/AssignAction.java | 12 +- .../AssignOriginalSubmitterAction.java | 28 +- .../userassignment/AutoAssignAction.java | 18 +- .../actions/userassignment/ClaimAction.java | 30 +- .../userassignment/InheritUsersAction.java | 12 +- .../userassignment/NoUserSelectionAction.java | 12 +- .../userassignment/UserSelectionAction.java | 10 +- .../storedcomponents/ClaimedTask.java | 7 +- .../ClaimedTaskServiceImpl.java | 15 +- .../storedcomponents/InProgressUser.java | 7 +- .../InProgressUserServiceImpl.java | 9 +- .../storedcomponents/PoolTask.java | 9 +- .../storedcomponents/PoolTaskServiceImpl.java | 11 +- .../storedcomponents/WorkflowItemRole.java | 9 +- .../WorkflowItemRoleServiceImpl.java | 11 +- .../storedcomponents/XmlWorkflowItem.java} | 9 +- .../XmlWorkflowItemServiceImpl.java} | 84 +-- .../storedcomponents/dao/ClaimedTaskDAO.java | 12 +- .../dao/InProgressUserDAO.java | 10 +- .../storedcomponents/dao/PoolTaskDAO.java | 8 +- .../dao/WorkflowItemRoleDAO.java | 6 +- ...owItemDAO.java => XmlWorkflowItemDAO.java} | 20 +- .../dao/impl/ClaimedTaskDAOImpl.java | 12 +- .../dao/impl/InProgressUserDAOImpl.java | 10 +- .../dao/impl/PoolTaskDAOImpl.java | 8 +- .../dao/impl/WorkflowItemDAOImpl.java | 137 ----- .../dao/impl/WorkflowItemRoleDAOImpl.java | 6 +- .../dao/impl/XmlWorkflowItemDAOImpl.java | 137 +++++ .../service/ClaimedTaskService.java | 16 +- .../service/InProgressUserService.java | 10 +- .../service/PoolTaskService.java | 8 +- .../service/WorkflowItemRoleService.java | 8 +- .../service/XmlWorkflowItemService.java} | 32 +- .../org/dspace/builder/AbstractBuilder.java | 22 +- .../dspace/builder/ClaimedTaskBuilder.java | 10 +- .../org/dspace/builder/PoolTaskBuilder.java | 4 +- .../dspace/builder/WorkflowItemBuilder.java | 16 +- .../dspace/builder/WorkspaceItemBuilder.java | 4 +- .../org/dspace/discovery/DiscoveryIT.java | 24 +- .../dspace/eperson/EPersonInWorkflowIT.java | 530 +++++++++--------- .../java/org/dspace/eperson/EPersonTest.java | 14 +- .../identifier/DOIIdentifierProviderTest.java | 6 +- .../EZIDIdentifierProviderTest.java | 6 +- .../xmlworkflow/XmlWorkflowFactoryTest.java | 4 +- .../org/dspace/rest/CollectionsResource.java | 6 +- .../rest/CollectionGroupRestController.java | 4 +- .../rest/converter/ClaimedTaskConverter.java | 4 +- .../app/rest/converter/PoolTaskConverter.java | 4 +- .../rest/converter/WorkflowItemConverter.java | 12 +- .../repository/ClaimedTaskRestRepository.java | 12 +- .../repository/CollectionRestRepository.java | 4 +- .../repository/PoolTaskRestRepository.java | 8 +- .../WorkflowItemRestRepository.java | 44 +- .../WorkflowItemStepLinkRepository.java | 20 +- ...PoolTaskRestPermissionEvaluatorPlugin.java | 4 +- ...WorkflowRestPermissionEvaluatorPlugin.java | 8 +- .../app/rest/submit/SubmissionService.java | 16 +- .../rest/CollectionGroupRestControllerIT.java | 4 +- .../app/rest/DiscoveryRestControllerIT.java | 18 +- .../app/rest/EPersonRestRepositoryIT.java | 4 +- .../org/dspace/app/rest/LoginAsEPersonIT.java | 4 +- .../app/rest/TaskRestRepositoriesIT.java | 110 ++-- .../rest/WorkflowActionRestRepositoryIT.java | 4 +- .../WorkflowDefinitionRestRepositoryIT.java | 4 +- .../rest/WorkflowItemRestRepositoryIT.java | 80 +-- .../rest/WorkflowStepRestRepositoryIT.java | 4 +- .../authorization/ReinstateFeatureRestIT.java | 4 +- .../authorization/WithdrawFeatureRestIT.java | 4 +- .../eperson/DeleteEPersonSubmitterIT.java | 16 +- .../matcher/WorkflowDefinitionMatcher.java | 4 +- .../app/rest/matcher/WorkflowItemMatcher.java | 16 +- .../sword2/CollectionListManagerDSpace.java | 14 +- .../dspace/sword2/ContainerManagerDSpace.java | 12 +- .../java/org/dspace/sword2/WorkflowTools.java | 20 +- dspace/config/hibernate.cfg.xml | 2 +- .../config/spring/api/core-dao-services.xml | 2 +- .../spring/api/core-factory-services.xml | 2 +- dspace/config/spring/api/core-services.xml | 4 +- dspace/config/spring/api/discovery.xml | 4 +- 124 files changed, 1179 insertions(+), 1205 deletions(-) rename dspace-api/src/main/java/org/dspace/xmlworkflow/{WorkflowServiceImpl.java => XmlWorkflowServiceImpl.java} (95%) rename dspace-api/src/main/java/org/dspace/{workflow/factory/WorkflowServiceFactory.java => xmlworkflow/factory/XmlWorkflowServiceFactory.java} (69%) rename dspace-api/src/main/java/org/dspace/{workflow/factory/WorkflowServiceFactoryImpl.java => xmlworkflow/factory/XmlWorkflowServiceFactoryImpl.java} (81%) rename dspace-api/src/main/java/org/dspace/{workflow/WorkflowService.java => xmlworkflow/service/XmlWorkflowService.java} (80%) rename dspace-api/src/main/java/org/dspace/{workflow/WorkflowItem.java => xmlworkflow/storedcomponents/XmlWorkflowItem.java} (91%) rename dspace-api/src/main/java/org/dspace/{workflow/WorkflowItemServiceImpl.java => xmlworkflow/storedcomponents/XmlWorkflowItemServiceImpl.java} (60%) rename dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/{WorkflowItemDAO.java => XmlWorkflowItemDAO.java} (72%) delete mode 100644 dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemDAOImpl.java create mode 100644 dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/XmlWorkflowItemDAOImpl.java rename dspace-api/src/main/java/org/dspace/{workflow/WorkflowItemService.java => xmlworkflow/storedcomponents/service/XmlWorkflowItemService.java} (82%) diff --git a/dspace-api/src/main/java/org/dspace/app/bulkedit/MetadataImport.java b/dspace-api/src/main/java/org/dspace/app/bulkedit/MetadataImport.java index 97a474db31..f94fc67f2b 100644 --- a/dspace-api/src/main/java/org/dspace/app/bulkedit/MetadataImport.java +++ b/dspace-api/src/main/java/org/dspace/app/bulkedit/MetadataImport.java @@ -64,9 +64,9 @@ import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.utils.DSpace; import org.dspace.workflow.WorkflowException; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowService; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.xmlworkflow.service.XmlWorkflowService; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Metadata importer to allow the batch import of metadata from a file @@ -370,7 +370,7 @@ public class MetadataImport extends DSpaceRunnable i } - WorkflowServiceFactory.getInstance().getWorkflowService().deleteCollection(context, collection); - WorkflowServiceFactory.getInstance().getWorkflowItemService().deleteByCollection(context, collection); + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService().deleteCollection(context, collection); + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService().deleteByCollection(context, collection); // get rid of the content count cache if it exists // Remove any Handle diff --git a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java index a2e9553ba5..b60c23b164 100644 --- a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java @@ -55,8 +55,8 @@ import org.dspace.identifier.IdentifierException; import org.dspace.identifier.service.IdentifierService; import org.dspace.services.ConfigurationService; import org.dspace.versioning.service.VersioningService; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -106,7 +106,7 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl implements It @Autowired(required = true) protected WorkspaceItemService workspaceItemService; @Autowired(required = true) - protected WorkflowItemService workflowItemService; + protected XmlWorkflowItemService workflowItemService; @Autowired(required = true) protected RelationshipService relationshipService; @@ -1138,7 +1138,7 @@ prevent the generation of resource policy entry values with null dspace_object a .findByItem(context, item); if (inprogress == null) { - inprogress = WorkflowServiceFactory.getInstance().getWorkflowItemService().findByItem(context, item); + inprogress = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService().findByItem(context, item); } if (inprogress != null) { diff --git a/dspace-api/src/main/java/org/dspace/content/WorkspaceItem.java b/dspace-api/src/main/java/org/dspace/content/WorkspaceItem.java index 8049aa976c..4c01de3870 100644 --- a/dspace-api/src/main/java/org/dspace/content/WorkspaceItem.java +++ b/dspace-api/src/main/java/org/dspace/content/WorkspaceItem.java @@ -28,7 +28,7 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; -import org.dspace.workflow.WorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.hibernate.proxy.HibernateProxyHelper; /** @@ -90,7 +90,7 @@ public class WorkspaceItem * Protected constructor, create object using: * {@link org.dspace.content.service.WorkspaceItemService#create(Context, Collection, boolean)} * or - * {@link org.dspace.content.service.WorkspaceItemService#create(Context, WorkflowItem)} + * {@link org.dspace.content.service.WorkspaceItemService#create(Context, XmlWorkflowItem)} */ protected WorkspaceItem() { diff --git a/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java index 8fc302f8bf..8fff023226 100644 --- a/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java @@ -28,8 +28,8 @@ import org.dspace.core.Context; import org.dspace.core.LogManager; import org.dspace.eperson.EPerson; import org.dspace.event.Event; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowService; +import org.dspace.xmlworkflow.service.XmlWorkflowService; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.springframework.beans.factory.annotation.Autowired; /** @@ -53,7 +53,7 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService { @Autowired(required = true) protected ItemService itemService; @Autowired(required = true) - protected WorkflowService workflowService; + protected XmlWorkflowService workflowService; protected WorkspaceItemServiceImpl() { @@ -138,7 +138,7 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService { } @Override - public WorkspaceItem create(Context c, WorkflowItem workflowItem) throws SQLException, AuthorizeException { + public WorkspaceItem create(Context c, XmlWorkflowItem workflowItem) throws SQLException, AuthorizeException { WorkspaceItem workspaceItem = workspaceItemDAO.create(c, new WorkspaceItem()); workspaceItem.setItem(workflowItem.getItem()); workspaceItem.setCollection(workflowItem.getCollection()); diff --git a/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java b/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java index 4010e14861..31c137fb64 100644 --- a/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java +++ b/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java @@ -34,7 +34,7 @@ import org.dspace.content.service.SiteService; import org.dspace.content.service.SupervisedItemService; import org.dspace.content.service.WorkspaceItemService; import org.dspace.services.factory.DSpaceServicesFactory; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; /** * Abstract factory to get services for the content package, use ContentServiceFactory.getInstance() to retrieve an @@ -109,7 +109,7 @@ public abstract class ContentServiceFactory { if (inProgressSubmission instanceof WorkspaceItem) { return getWorkspaceItemService(); } else { - return WorkflowServiceFactory.getInstance().getWorkflowItemService(); + return XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService(); } } diff --git a/dspace-api/src/main/java/org/dspace/content/packager/AbstractMETSIngester.java b/dspace-api/src/main/java/org/dspace/content/packager/AbstractMETSIngester.java index 0db9a98b9a..6304e88527 100644 --- a/dspace-api/src/main/java/org/dspace/content/packager/AbstractMETSIngester.java +++ b/dspace-api/src/main/java/org/dspace/content/packager/AbstractMETSIngester.java @@ -49,7 +49,7 @@ import org.dspace.handle.service.HandleService; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.workflow.WorkflowException; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.jdom.Element; /** @@ -628,7 +628,7 @@ public abstract class AbstractMETSIngester extends AbstractPackageIngester { //We are probably dealing with an item that isn't archived yet InProgressSubmission inProgressSubmission = workspaceItemService.findByItem(context, item); if (inProgressSubmission == null) { - inProgressSubmission = WorkflowServiceFactory.getInstance().getWorkflowItemService() + inProgressSubmission = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService() .findByItem(context, item); } owningCollection = inProgressSubmission.getCollection(); diff --git a/dspace-api/src/main/java/org/dspace/content/packager/PackageUtils.java b/dspace-api/src/main/java/org/dspace/content/packager/PackageUtils.java index e45aa7d699..c050ce4b2a 100644 --- a/dspace-api/src/main/java/org/dspace/content/packager/PackageUtils.java +++ b/dspace-api/src/main/java/org/dspace/content/packager/PackageUtils.java @@ -52,8 +52,8 @@ import org.dspace.handle.factory.HandleServiceFactory; import org.dspace.handle.service.HandleService; import org.dspace.license.service.CreativeCommonsService; import org.dspace.workflow.WorkflowException; -import org.dspace.workflow.WorkflowService; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.xmlworkflow.service.XmlWorkflowService; /** * Container class for code that is useful to many packagers. @@ -520,7 +520,7 @@ public class PackageUtils { } else if (params.workflowEnabled()) { // if we are treating package as a SIP, and we are told to respect workflows - WorkflowService workflowService = WorkflowServiceFactory.getInstance().getWorkflowService(); + XmlWorkflowService workflowService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); // Start an item workflow // (NOTICE: The specified handle is ignored, as Workflows *always* end in a new handle being assigned) return workflowService.startWithoutNotify(context, wsi).getItem(); diff --git a/dspace-api/src/main/java/org/dspace/content/service/WorkspaceItemService.java b/dspace-api/src/main/java/org/dspace/content/service/WorkspaceItemService.java index 3ee381706c..acf17fc8e3 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/WorkspaceItemService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/WorkspaceItemService.java @@ -18,7 +18,7 @@ import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Service interface class for the WorkspaceItem object. @@ -55,7 +55,7 @@ public interface WorkspaceItemService extends InProgressSubmissionService getAllDiscoveryConfigurations(WorkflowItem witem) throws SQLException { + public static List getAllDiscoveryConfigurations(XmlWorkflowItem witem) throws SQLException { List collections = new ArrayList(); collections.add(witem.getCollection()); return getAllDiscoveryConfigurations("workflow", collections, witem.getItem()); diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexableWorkflowItem.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexableWorkflowItem.java index 744cb174fb..016fec1bbb 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexableWorkflowItem.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexableWorkflowItem.java @@ -7,17 +7,17 @@ */ package org.dspace.discovery.indexobject; -import org.dspace.workflow.WorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Workflow item implementation for the IndexableObject * @author Kevin Van de Velde (kevin at atmire dot com) */ -public class IndexableWorkflowItem extends IndexableInProgressSubmission { +public class IndexableWorkflowItem extends IndexableInProgressSubmission { - public static final String TYPE = WorkflowItem.class.getSimpleName(); + public static final String TYPE = XmlWorkflowItem.class.getSimpleName(); - public IndexableWorkflowItem(WorkflowItem inProgressSubmission) { + public IndexableWorkflowItem(XmlWorkflowItem inProgressSubmission) { super(inProgressSubmission); } diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java index 6922665d07..07948bb0c3 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java @@ -64,8 +64,8 @@ import org.dspace.handle.service.HandleService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.util.MultiFormatDateParser; import org.dspace.util.SolrUtils; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowItemService; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -91,7 +91,7 @@ public class ItemIndexFactoryImpl extends DSpaceObjectIndexFactoryImpl + extends InprogressSubmissionIndexFactoryImpl implements WorkflowItemIndexFactory { @Autowired - protected WorkflowItemService workflowItemService; + protected XmlWorkflowItemService workflowItemService; @Autowired protected ClaimedTaskService claimedTaskService; @Autowired @@ -48,7 +48,7 @@ public class WorkflowItemIndexFactoryImpl @Override public Iterator findAll(Context context) throws SQLException { - final Iterator workflowItems = workflowItemService.findAll(context).iterator(); + final Iterator workflowItems = workflowItemService.findAll(context).iterator(); return new Iterator() { @Override @@ -73,7 +73,7 @@ public class WorkflowItemIndexFactoryImpl throws SQLException, IOException { // Add the ID's, types and call the SolrServiceIndexPlugins final SolrInputDocument doc = super.buildDocument(context, indexableObject); - final WorkflowItem workflowItem = indexableObject.getIndexedObject(); + final XmlWorkflowItem workflowItem = indexableObject.getIndexedObject(); final Item item = workflowItem.getItem(); // Add the item metadata as configured List discoveryConfigurations = SearchUtils @@ -92,11 +92,11 @@ public class WorkflowItemIndexFactoryImpl @Override public boolean supports(Object object) { - return object instanceof WorkflowItem; + return object instanceof XmlWorkflowItem; } @Override - public List getIndexableObjects(Context context, WorkflowItem object) throws SQLException { + public List getIndexableObjects(Context context, XmlWorkflowItem object) throws SQLException { List results = new ArrayList<>(); results.add(new IndexableWorkflowItem(object)); @@ -115,7 +115,7 @@ public class WorkflowItemIndexFactoryImpl @Override public Optional findIndexableObject(Context context, String id) throws SQLException { - final WorkflowItem workflowItem = workflowItemService.find(context, Integer.parseInt(id)); - return workflowItem == null ? Optional.empty() : Optional.of(new IndexableWorkflowItem(workflowItem)); + final XmlWorkflowItem xmlWorkflowItem = workflowItemService.find(context, Integer.parseInt(id)); + return xmlWorkflowItem == null ? Optional.empty() : Optional.of(new IndexableWorkflowItem(xmlWorkflowItem)); } } \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/IndexObjectFactoryFactory.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/IndexObjectFactoryFactory.java index eb287ce937..5f7ac63cb1 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/IndexObjectFactoryFactory.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/IndexObjectFactoryFactory.java @@ -15,9 +15,9 @@ import org.dspace.content.service.WorkspaceItemService; import org.dspace.core.Context; import org.dspace.discovery.IndexableObject; import org.dspace.services.factory.DSpaceServicesFactory; -import org.dspace.workflow.WorkflowItemService; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -29,7 +29,7 @@ public abstract class IndexObjectFactoryFactory { @Autowired protected WorkspaceItemService workspaceItemService; @Autowired - protected WorkflowItemService workflowItemService; + protected XmlWorkflowItemService xmlWorkflowItemService; @Autowired protected ClaimedTaskService claimedTaskService; @Autowired diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/WorkflowItemIndexFactory.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/WorkflowItemIndexFactory.java index 78be29128f..2a2f695ed8 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/WorkflowItemIndexFactory.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/WorkflowItemIndexFactory.java @@ -8,7 +8,7 @@ package org.dspace.discovery.indexobject.factory; import org.dspace.discovery.indexobject.IndexableWorkflowItem; -import org.dspace.workflow.WorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Factory interface for indexing/retrieving workflow items objects in the search core @@ -16,5 +16,5 @@ import org.dspace.workflow.WorkflowItem; * @author Kevin Van de Velde (kevin at atmire dot com) */ public interface WorkflowItemIndexFactory - extends InprogressSubmissionIndexFactory { + extends InprogressSubmissionIndexFactory { } \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java b/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java index 909e97abbb..938a167f6f 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java @@ -49,11 +49,10 @@ import org.dspace.versioning.dao.VersionDAO; import org.dspace.versioning.factory.VersionServiceFactory; import org.dspace.versioning.service.VersionHistoryService; import org.dspace.versioning.service.VersioningService; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflow.WorkflowService; -import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.WorkflowConfigurationException; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; +import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.CollectionRole; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; @@ -321,19 +320,17 @@ public class EPersonServiceImpl extends DSpaceObjectServiceImpl impleme } } else if (StringUtils.equals(tableName, "cwf_claimtask")) { // Unclaim all XmlWorkflow tasks - WorkflowItemService workflowItemService = WorkflowServiceFactory - .getInstance().getWorkflowItemService(); - ClaimedTaskService claimedTaskService = WorkflowServiceFactory + ClaimedTaskService claimedTaskService = XmlWorkflowServiceFactory .getInstance().getClaimedTaskService(); - WorkflowService workflowService = WorkflowServiceFactory - .getInstance().getWorkflowService(); - WorkflowRequirementsService workflowRequirementsService = WorkflowServiceFactory + XmlWorkflowService xmlWorkflowService = XmlWorkflowServiceFactory + .getInstance().getXmlWorkflowService(); + WorkflowRequirementsService workflowRequirementsService = XmlWorkflowServiceFactory .getInstance().getWorkflowRequirementsService(); List claimedTasks = claimedTaskService.findByEperson(context, ePerson); for (ClaimedTask task : claimedTasks) { - workflowService.deleteClaimedTask(context, task.getWorkflowItem(), task); + xmlWorkflowService.deleteClaimedTask(context, task.getWorkflowItem(), task); try { workflowRequirementsService.removeClaimedUser(context, task.getWorkflowItem(), @@ -349,10 +346,10 @@ public class EPersonServiceImpl extends DSpaceObjectServiceImpl impleme // we delete the EPerson, it won't need any rights anymore. authorizeService.removeAllEPersonPolicies(context, ePerson); } else if (StringUtils.equals(tableName, "cwf_pooltask")) { - PoolTaskService poolTaskService = WorkflowServiceFactory.getInstance().getPoolTaskService(); + PoolTaskService poolTaskService = XmlWorkflowServiceFactory.getInstance().getPoolTaskService(); poolTaskService.deleteByEperson(context, ePerson); } else if (StringUtils.equals(tableName, "cwf_workflowitemrole")) { - WorkflowItemRoleService workflowItemRoleService = WorkflowServiceFactory.getInstance() + WorkflowItemRoleService workflowItemRoleService = XmlWorkflowServiceFactory.getInstance() .getWorkflowItemRoleService(); workflowItemRoleService.deleteByEPerson(context, ePerson); } else { @@ -521,7 +518,7 @@ public class EPersonServiceImpl extends DSpaceObjectServiceImpl impleme tableList.add("resourcepolicy"); } - WorkflowService workflowService = WorkflowServiceFactory.getInstance().getWorkflowService(); + XmlWorkflowService workflowService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); List workflowConstraints = workflowService.getEPersonDeleteConstraints(context, ePerson); tableList.addAll(workflowConstraints); diff --git a/dspace-api/src/main/java/org/dspace/health/ItemCheck.java b/dspace-api/src/main/java/org/dspace/health/ItemCheck.java index cc7802d792..2204049bbb 100644 --- a/dspace-api/src/main/java/org/dspace/health/ItemCheck.java +++ b/dspace-api/src/main/java/org/dspace/health/ItemCheck.java @@ -33,8 +33,8 @@ import org.dspace.eperson.service.EPersonService; import org.dspace.eperson.service.GroupService; import org.dspace.handle.factory.HandleServiceFactory; import org.dspace.handle.service.HandleService; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; /** * @author LINDAT/CLARIN dev team @@ -48,8 +48,8 @@ public class ItemCheck extends Check { private MetadataValueService metadataValueService = ContentServiceFactory.getInstance().getMetadataValueService(); private ItemService itemService = ContentServiceFactory.getInstance().getItemService(); private WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); - private WorkflowItemService workflowItemService = - WorkflowServiceFactory.getInstance().getWorkflowItemService(); + private XmlWorkflowItemService workflowItemService = + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService(); private HandleService handleService = HandleServiceFactory.getInstance().getHandleService(); private EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); private GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); diff --git a/dspace-api/src/main/java/org/dspace/identifier/doi/DOIConsumer.java b/dspace-api/src/main/java/org/dspace/identifier/doi/DOIConsumer.java index 654d275d87..ea8054aada 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/doi/DOIConsumer.java +++ b/dspace-api/src/main/java/org/dspace/identifier/doi/DOIConsumer.java @@ -19,7 +19,7 @@ import org.dspace.identifier.DOIIdentifierProvider; import org.dspace.identifier.IdentifierException; import org.dspace.identifier.IdentifierNotFoundException; import org.dspace.utils.DSpace; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; /** * @author Pascal-Nicolas Becker (p dot becker at tu hyphen berlin dot de) @@ -64,7 +64,7 @@ public class DOIConsumer implements Consumer { Item item = (Item) dso; if (ContentServiceFactory.getInstance().getWorkspaceItemService().findByItem(ctx, item) != null - || WorkflowServiceFactory.getInstance().getWorkflowItemService().findByItem(ctx, item) != null) { + || XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService().findByItem(ctx, item) != null) { // ignore workflow and workspace items, DOI will be minted when item is installed return; } diff --git a/dspace-api/src/main/java/org/dspace/rdf/RDFConsumer.java b/dspace-api/src/main/java/org/dspace/rdf/RDFConsumer.java index 76ae0cd2d2..ae11205a64 100644 --- a/dspace-api/src/main/java/org/dspace/rdf/RDFConsumer.java +++ b/dspace-api/src/main/java/org/dspace/rdf/RDFConsumer.java @@ -33,8 +33,8 @@ import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.event.Consumer; import org.dspace.event.Event; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; /** * @author Pascal-Nicolas Becker (dspace -at- pascal -hyphen- becker -dot- de) @@ -49,7 +49,7 @@ public class RDFConsumer implements Consumer { protected BundleService bundleService; protected SiteService siteService; protected WorkspaceItemService workspaceItemService; - protected WorkflowItemService workflowItemService; + protected XmlWorkflowItemService workflowItemService; @Override public void initialize() throws Exception { @@ -57,7 +57,7 @@ public class RDFConsumer implements Consumer { bundleService = ContentServiceFactory.getInstance().getBundleService(); siteService = ContentServiceFactory.getInstance().getSiteService(); workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); - workflowItemService = WorkflowServiceFactory.getInstance().getWorkflowItemService(); + workflowItemService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService(); } @Override diff --git a/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseUtils.java b/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseUtils.java index 5f8e72a535..39e4b8abd0 100644 --- a/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseUtils.java +++ b/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseUtils.java @@ -32,7 +32,7 @@ import org.dspace.discovery.IndexingService; import org.dspace.discovery.SearchServiceException; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.flywaydb.core.Flyway; import org.flywaydb.core.api.FlywayException; import org.flywaydb.core.api.MigrationInfo; @@ -557,8 +557,8 @@ public class DatabaseUtils { scriptLocations.add("classpath:org/dspace/storage/rdbms/migration"); //Add all potential workflow migration paths - List workflowFlywayMigrationLocations = WorkflowServiceFactory.getInstance() - .getWorkflowService() + List workflowFlywayMigrationLocations = XmlWorkflowServiceFactory.getInstance() + .getXmlWorkflowService() .getFlywayMigrationLocations(); scriptLocations.addAll(workflowFlywayMigrationLocations); diff --git a/dspace-api/src/main/java/org/dspace/versioning/DefaultItemVersionProvider.java b/dspace-api/src/main/java/org/dspace/versioning/DefaultItemVersionProvider.java index 7903a49c31..9934ca5085 100644 --- a/dspace-api/src/main/java/org/dspace/versioning/DefaultItemVersionProvider.java +++ b/dspace-api/src/main/java/org/dspace/versioning/DefaultItemVersionProvider.java @@ -22,7 +22,7 @@ import org.dspace.identifier.IdentifierException; import org.dspace.identifier.service.IdentifierService; import org.dspace.versioning.service.VersionHistoryService; import org.dspace.versioning.service.VersioningService; -import org.dspace.workflow.WorkflowItemService; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -37,7 +37,7 @@ public class DefaultItemVersionProvider extends AbstractVersionProvider implemen @Autowired(required = true) protected WorkspaceItemService workspaceItemService; @Autowired(required = true) - protected WorkflowItemService workflowItemService; + protected XmlWorkflowItemService workflowItemService; @Autowired(required = true) protected VersionHistoryService versionHistoryService; @Autowired(required = true) diff --git a/dspace-api/src/main/java/org/dspace/versioning/VersioningServiceImpl.java b/dspace-api/src/main/java/org/dspace/versioning/VersioningServiceImpl.java index ee6adf9098..060bc678f6 100644 --- a/dspace-api/src/main/java/org/dspace/versioning/VersioningServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/versioning/VersioningServiceImpl.java @@ -21,8 +21,8 @@ import org.dspace.core.Context; import org.dspace.versioning.dao.VersionDAO; import org.dspace.versioning.service.VersionHistoryService; import org.dspace.versioning.service.VersioningService; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowItemService; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -42,7 +42,7 @@ public class VersioningServiceImpl implements VersioningService { @Autowired(required = true) private WorkspaceItemService workspaceItemService; @Autowired(required = true) - protected WorkflowItemService workflowItemService; + protected XmlWorkflowItemService workflowItemService; private DefaultItemVersionProvider provider; @@ -139,7 +139,7 @@ public class VersioningServiceImpl implements VersioningService { if (wsi != null) { workspaceItemService.deleteAll(c, wsi); } else { - WorkflowItem wfi = workflowItemService.findByItem(c, item); + XmlWorkflowItem wfi = workflowItemService.findByItem(c, item); if (wfi != null) { workflowItemService.delete(c, wfi); } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/Role.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/Role.java index 03ad4b7935..bfc5654cdd 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/Role.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/Role.java @@ -14,9 +14,9 @@ import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; import org.dspace.eperson.service.GroupService; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.CollectionRole; import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; import org.springframework.beans.factory.BeanNameAware; @@ -79,7 +79,7 @@ public class Role implements BeanNameAware { return scope; } - public RoleMembers getMembers(Context context, WorkflowItem wfi) throws SQLException { + public RoleMembers getMembers(Context context, XmlWorkflowItem wfi) throws SQLException { if (scope == Scope.REPOSITORY) { Group group = groupService.findByName(context, name); if (group == null) { diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowRequirementsServiceImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowRequirementsServiceImpl.java index 9111ff44f5..c651097fcb 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowRequirementsServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowRequirementsServiceImpl.java @@ -17,17 +17,17 @@ import org.dspace.authorize.ResourcePolicy; import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflow.WorkflowService; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; +import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.storedcomponents.InProgressUser; import org.dspace.xmlworkflow.storedcomponents.PoolTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -52,22 +52,22 @@ public class WorkflowRequirementsServiceImpl implements WorkflowRequirementsServ @Autowired(required = true) protected XmlWorkflowFactory workflowFactory; @Autowired(required = true) - protected WorkflowItemService workflowItemService; + protected XmlWorkflowItemService xmlWorkflowItemService; @Autowired(required = true) - protected WorkflowService workflowService; + protected XmlWorkflowService xmlWorkflowService; protected WorkflowRequirementsServiceImpl() { } @Override - public void addClaimedUser(Context context, WorkflowItem wfi, Step step, EPerson user) + public void addClaimedUser(Context context, XmlWorkflowItem wfi, Step step, EPerson user) throws SQLException, AuthorizeException, IOException { //Make sure we delete the pooled task for our current user if the task is not a group pooltask PoolTask task = poolTaskService.findByWorkflowIdAndEPerson(context, wfi, user); if (task != null && task.getEperson() != null) { - workflowService.deletePooledTask(context, wfi, task); + xmlWorkflowService.deletePooledTask(context, wfi, task); } InProgressUser ipu = inProgressUserService.create(context); @@ -77,21 +77,21 @@ public class WorkflowRequirementsServiceImpl implements WorkflowRequirementsServ inProgressUserService.update(context, ipu); //Make sure the user has the necessary rights to update the item after the tasks is removed from the pool - workflowService.grantUserAllItemPolicies(context, wfi.getItem(), user, ResourcePolicy.TYPE_WORKFLOW); + xmlWorkflowService.grantUserAllItemPolicies(context, wfi.getItem(), user, ResourcePolicy.TYPE_WORKFLOW); int totalUsers = inProgressUserService.getNumberOfInProgressUsers(context, wfi) + inProgressUserService .getNumberOfFinishedUsers(context, wfi); if (totalUsers == step.getRequiredUsers()) { //If enough users have claimed/finished this step then remove the tasks - workflowService.deleteAllPooledTasks(context, wfi); + xmlWorkflowService.deleteAllPooledTasks(context, wfi); } - workflowItemService.update(context, wfi); + xmlWorkflowItemService.update(context, wfi); } @Override - public void removeClaimedUser(Context context, WorkflowItem wfi, EPerson user, String stepID) + public void removeClaimedUser(Context context, XmlWorkflowItem wfi, EPerson user, String stepID) throws SQLException, IOException, WorkflowConfigurationException, AuthorizeException { //Check if we had reached our max number @ this moment int totalUsers = inProgressUserService.getNumberOfInProgressUsers(context, wfi) + inProgressUserService @@ -101,7 +101,7 @@ public class WorkflowRequirementsServiceImpl implements WorkflowRequirementsServ inProgressUserService.delete(context, inProgressUserService.findByWorkflowItemAndEPerson(context, wfi, user)); //Make sure the removed user has his custom rights removed - workflowService.removeUserItemPolicies(context, wfi.getItem(), user); + xmlWorkflowService.removeUserItemPolicies(context, wfi.getItem(), user); Workflow workflow = workflowFactory.getWorkflow(wfi.getCollection()); Step step = workflow.getStep(stepID); @@ -142,7 +142,7 @@ public class WorkflowRequirementsServiceImpl implements WorkflowRequirementsServ } @Override - public void addFinishedUser(Context c, WorkflowItem wfi, EPerson user) throws AuthorizeException, SQLException { + public void addFinishedUser(Context c, XmlWorkflowItem wfi, EPerson user) throws AuthorizeException, SQLException { InProgressUser ipu = inProgressUserService.findByWorkflowItemAndEPerson(c, wfi, user); ipu.setFinished(true); inProgressUserService.update(c, ipu); @@ -150,7 +150,7 @@ public class WorkflowRequirementsServiceImpl implements WorkflowRequirementsServ @Override - public void clearInProgressUsers(Context c, WorkflowItem wfi) throws AuthorizeException, SQLException { + public void clearInProgressUsers(Context c, XmlWorkflowItem wfi) throws AuthorizeException, SQLException { Iterator ipus = inProgressUserService.findByWorkflowItem(c, wfi).iterator(); while (ipus.hasNext()) { InProgressUser ipu = ipus.next(); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowUtils.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowUtils.java index 7e24e3e1cd..03cd105ca4 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowUtils.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowUtils.java @@ -32,8 +32,8 @@ import org.dspace.eperson.factory.EPersonServiceFactory; import org.dspace.eperson.service.GroupService; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; -import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.storedcomponents.CollectionRole; import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService; @@ -53,9 +53,9 @@ public class WorkflowUtils extends Util { public static Logger log = LogManager.getLogger(WorkflowUtils.class); protected static final CollectionRoleService collectionRoleService = - WorkflowServiceFactory.getInstance().getCollectionRoleService(); + XmlWorkflowServiceFactory.getInstance().getCollectionRoleService(); protected static final GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - protected static final XmlWorkflowFactory xmlWorkflowFactory = WorkflowServiceFactory.getInstance() + protected static final XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance() .getWorkflowFactory(); protected static final ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowServiceImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/XmlWorkflowServiceImpl.java similarity index 95% rename from dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowServiceImpl.java rename to dspace-api/src/main/java/org/dspace/xmlworkflow/XmlWorkflowServiceImpl.java index 34f3446b2a..4da863b65c 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/WorkflowServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/XmlWorkflowServiceImpl.java @@ -54,11 +54,9 @@ import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.usage.UsageWorkflowEvent; import org.dspace.workflow.WorkflowException; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflow.WorkflowService; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; +import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.state.actions.Action; @@ -66,10 +64,12 @@ import org.dspace.xmlworkflow.state.actions.ActionResult; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.PoolTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -83,12 +83,12 @@ import org.springframework.beans.factory.annotation.Autowired; * @author Ben Bosman (ben at atmire dot com) * @author Mark Diggory (markd at atmire dot com) */ -public class WorkflowServiceImpl implements WorkflowService { +public class XmlWorkflowServiceImpl implements XmlWorkflowService { /* support for 'no notification' */ protected Map noEMail = new HashMap<>(); - private final Logger log = org.apache.logging.log4j.LogManager.getLogger(WorkflowServiceImpl.class); + private final Logger log = org.apache.logging.log4j.LogManager.getLogger(XmlWorkflowServiceImpl.class); @Autowired(required = true) protected AuthorizeService authorizeService; @@ -113,7 +113,7 @@ public class WorkflowServiceImpl implements WorkflowService { @Autowired(required = true) protected WorkspaceItemService workspaceItemService; @Autowired(required = true) - protected WorkflowItemService workflowItemService; + protected XmlWorkflowItemService xmlWorkflowItemService; @Autowired(required = true) protected GroupService groupService; @Autowired(required = true) @@ -125,7 +125,7 @@ public class WorkflowServiceImpl implements WorkflowService { @Autowired(required = true) protected ConfigurationService configurationService; - protected WorkflowServiceImpl() { + protected XmlWorkflowServiceImpl() { } @@ -133,7 +133,7 @@ public class WorkflowServiceImpl implements WorkflowService { @Override public void deleteCollection(Context context, Collection collection) throws SQLException, IOException, AuthorizeException { - workflowItemService.deleteByCollection(context, collection); + xmlWorkflowItemService.deleteByCollection(context, collection); collectionRoleService.deleteByCollection(context, collection); } @@ -194,18 +194,18 @@ public class WorkflowServiceImpl implements WorkflowService { } @Override - public WorkflowItem start(Context context, WorkspaceItem wsi) + public XmlWorkflowItem start(Context context, WorkspaceItem wsi) throws SQLException, AuthorizeException, IOException, WorkflowException { try { Item myitem = wsi.getItem(); Collection collection = wsi.getCollection(); Workflow wf = xmlWorkflowFactory.getWorkflow(collection); - WorkflowItem wfi = workflowItemService.create(context, myitem, collection); + XmlWorkflowItem wfi = xmlWorkflowItemService.create(context, myitem, collection); wfi.setMultipleFiles(wsi.hasMultipleFiles()); wfi.setMultipleTitles(wsi.hasMultipleTitles()); wfi.setPublishedBefore(wsi.isPublishedBefore()); - workflowItemService.update(context, wfi); + xmlWorkflowItemService.update(context, wfi); removeUserItemPolicies(context, myitem, myitem.getSubmitter()); grantSubmitterReadPolicies(context, myitem); @@ -244,7 +244,7 @@ public class WorkflowServiceImpl implements WorkflowService { * @param wsi the submitted Item entering workflow. */ @Override - public WorkflowItem startWithoutNotify(Context context, WorkspaceItem wsi) + public XmlWorkflowItem startWithoutNotify(Context context, WorkspaceItem wsi) throws SQLException, AuthorizeException, IOException, WorkflowException { // make a hash table entry with item ID for no notify // notify code checks no notify hash for item id @@ -254,7 +254,7 @@ public class WorkflowServiceImpl implements WorkflowService { } @Override - public void alertUsersOnTaskActivation(Context c, WorkflowItem wfi, String emailTemplate, List epa, + public void alertUsersOnTaskActivation(Context c, XmlWorkflowItem wfi, String emailTemplate, List epa, String... arguments) throws IOException, SQLException, MessagingException { if (noEMail.containsKey(wfi.getItem().getID())) { // suppress email, and delete key @@ -292,7 +292,7 @@ public class WorkflowServiceImpl implements WorkflowService { } - protected void activateFirstStep(Context context, Workflow wf, Step firstStep, WorkflowItem wfi) + protected void activateFirstStep(Context context, Workflow wf, Step firstStep, XmlWorkflowItem wfi) throws AuthorizeException, IOException, SQLException, WorkflowException, WorkflowConfigurationException { WorkflowActionConfig firstActionConfig = firstStep.getUserSelectionMethod(); firstActionConfig.getProcessingAction().activate(context, wfi); @@ -322,7 +322,7 @@ public class WorkflowServiceImpl implements WorkflowService { Workflow workflow, WorkflowActionConfig currentActionConfig) throws SQLException, AuthorizeException, IOException, WorkflowException { try { - WorkflowItem wi = workflowItemService.find(c, workflowItemId); + XmlWorkflowItem wi = xmlWorkflowItemService.find(c, workflowItemId); Step currentStep = currentActionConfig.getStep(); if (currentActionConfig.getProcessingAction().isAuthorized(c, request, wi)) { ActionResult outcome = currentActionConfig.getProcessingAction().execute(c, wi, currentStep, request); @@ -349,7 +349,7 @@ public class WorkflowServiceImpl implements WorkflowService { @Override public WorkflowActionConfig processOutcome(Context c, EPerson user, Workflow workflow, Step currentStep, WorkflowActionConfig currentActionConfig, ActionResult currentOutcome, - WorkflowItem wfi, boolean enteredNewStep) + XmlWorkflowItem wfi, boolean enteredNewStep) throws IOException, AuthorizeException, SQLException, WorkflowException { if (currentOutcome.getType() == ActionResult.TYPE.TYPE_PAGE || currentOutcome .getType() == ActionResult.TYPE.TYPE_ERROR) { @@ -460,7 +460,7 @@ public class WorkflowServiceImpl implements WorkflowService { } protected void logWorkflowEvent(Context c, String workflowId, String previousStepId, String previousActionConfigId, - WorkflowItem wfi, EPerson actor, Step newStep, + XmlWorkflowItem wfi, EPerson actor, Step newStep, WorkflowActionConfig newActionConfig) throws SQLException { try { //Fire an event so we can log our action ! @@ -510,7 +510,7 @@ public class WorkflowServiceImpl implements WorkflowService { } protected WorkflowActionConfig processNextStep(Context c, EPerson user, Workflow workflow, - ActionResult currentOutcome, WorkflowItem wfi, Step nextStep) + ActionResult currentOutcome, XmlWorkflowItem wfi, Step nextStep) throws SQLException, IOException, AuthorizeException, WorkflowException, WorkflowConfigurationException { WorkflowActionConfig nextActionConfig; if (nextStep != null) { @@ -552,7 +552,7 @@ public class WorkflowServiceImpl implements WorkflowService { * @throws AuthorizeException Exception indicating the current user of the context does not have permission * to perform a particular action. */ - protected Item archive(Context context, WorkflowItem wfi) + protected Item archive(Context context, XmlWorkflowItem wfi) throws SQLException, IOException, AuthorizeException { // FIXME: Check auth Item item = wfi.getItem(); @@ -644,7 +644,7 @@ public class WorkflowServiceImpl implements WorkflowService { * to perform a particular action. */ @Override - public void deleteAllTasks(Context context, WorkflowItem wi) throws SQLException, AuthorizeException { + public void deleteAllTasks(Context context, XmlWorkflowItem wi) throws SQLException, AuthorizeException { deleteAllPooledTasks(context, wi); Iterator allClaimedTasks = claimedTaskService.findByWorkflowItem(context, wi).iterator(); @@ -656,7 +656,7 @@ public class WorkflowServiceImpl implements WorkflowService { } @Override - public void deleteAllPooledTasks(Context context, WorkflowItem wi) throws SQLException, AuthorizeException { + public void deleteAllPooledTasks(Context context, XmlWorkflowItem wi) throws SQLException, AuthorizeException { Iterator allPooledTasks = poolTaskService.find(context, wi).iterator(); while (allPooledTasks.hasNext()) { PoolTask poolTask = allPooledTasks.next(); @@ -669,7 +669,7 @@ public class WorkflowServiceImpl implements WorkflowService { * Deletes an eperson from the taskpool of a step */ @Override - public void deletePooledTask(Context context, WorkflowItem wi, PoolTask task) + public void deletePooledTask(Context context, XmlWorkflowItem wi, PoolTask task) throws SQLException, AuthorizeException { if (task != null) { if (task.getEperson() != null) { @@ -682,7 +682,7 @@ public class WorkflowServiceImpl implements WorkflowService { } @Override - public void deleteClaimedTask(Context c, WorkflowItem wi, ClaimedTask task) + public void deleteClaimedTask(Context c, XmlWorkflowItem wi, ClaimedTask task) throws SQLException, AuthorizeException { if (task != null) { removeUserItemPolicies(c, wi.getItem(), task.getOwner()); @@ -696,7 +696,7 @@ public class WorkflowServiceImpl implements WorkflowService { * Creates a task pool for a given step */ @Override - public void createPoolTasks(Context context, WorkflowItem wi, RoleMembers assignees, Step step, + public void createPoolTasks(Context context, XmlWorkflowItem wi, RoleMembers assignees, Step step, WorkflowActionConfig action) throws SQLException, AuthorizeException { // create a tasklist entry for each eperson @@ -728,7 +728,7 @@ public class WorkflowServiceImpl implements WorkflowService { * Claims an action for a given eperson */ @Override - public void createOwnedTask(Context context, WorkflowItem wi, Step step, WorkflowActionConfig action, EPerson e) + public void createOwnedTask(Context context, XmlWorkflowItem wi, Step step, WorkflowActionConfig action, EPerson e) throws SQLException, AuthorizeException { ClaimedTask task = claimedTaskService.create(context); task.setWorkflowItem(wi); @@ -875,7 +875,7 @@ public class WorkflowServiceImpl implements WorkflowService { } @Override - public void deleteWorkflowByWorkflowItem(Context context, WorkflowItem wi, EPerson e) + public void deleteWorkflowByWorkflowItem(Context context, XmlWorkflowItem wi, EPerson e) throws SQLException, AuthorizeException, IOException { Item myitem = wi.getItem(); UUID itemID = myitem.getID(); @@ -889,7 +889,7 @@ public class WorkflowServiceImpl implements WorkflowService { // Remove (if any) the workflowItemroles for this item workflowItemRoleService.deleteForWorkflowItem(context, wi); // Now remove the workflow object manually from the database - workflowItemService.deleteWrapper(context, wi); + xmlWorkflowItemService.deleteWrapper(context, wi); // Now delete the item itemService.delete(context, myitem); log.info(LogManager.getHeader(context, "delete_workflow", "workflow_item_id=" @@ -900,9 +900,9 @@ public class WorkflowServiceImpl implements WorkflowService { } @Override - public WorkspaceItem sendWorkflowItemBackSubmission(Context context, WorkflowItem wi, EPerson e, - String provenance, - String rejection_message) + public WorkspaceItem sendWorkflowItemBackSubmission(Context context, XmlWorkflowItem wi, EPerson e, + String provenance, + String rejection_message) throws SQLException, AuthorizeException, IOException { @@ -962,7 +962,7 @@ public class WorkflowServiceImpl implements WorkflowService { } @Override - public WorkspaceItem abort(Context c, WorkflowItem wi, EPerson e) + public WorkspaceItem abort(Context c, XmlWorkflowItem wi, EPerson e) throws AuthorizeException, SQLException, IOException { if (!authorizeService.isAdmin(c)) { throw new AuthorizeException( @@ -991,13 +991,13 @@ public class WorkflowServiceImpl implements WorkflowService { * item is removed, and a workspace item created. * * @param c Context - * @param wfi workflow item to be 'dismantled' + * @param wfi WorkflowItem to be 'dismantled' * @return the workspace item * @throws java.io.IOException ... * @throws java.sql.SQLException ... * @throws org.dspace.authorize.AuthorizeException ... */ - protected WorkspaceItem returnToWorkspace(Context c, WorkflowItem wfi) + protected WorkspaceItem returnToWorkspace(Context c, XmlWorkflowItem wfi) throws SQLException, IOException, AuthorizeException { // authorize a DSpaceActions.REJECT // stop workflow @@ -1030,7 +1030,7 @@ public class WorkflowServiceImpl implements WorkflowService { + workspaceItem.getID())); // Now remove the workflow object manually from the database - workflowItemService.deleteWrapper(c, wfi); + xmlWorkflowItemService.deleteWrapper(c, wfi); return workspaceItem; } @@ -1072,7 +1072,7 @@ public class WorkflowServiceImpl implements WorkflowService { itemService.update(context, myitem); } - protected void notifyOfReject(Context c, WorkflowItem wi, EPerson e, + protected void notifyOfReject(Context c, XmlWorkflowItem wi, EPerson e, String reason) { try { // send the notification only if the person was not deleted in the diff --git a/dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactory.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactory.java similarity index 69% rename from dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactory.java rename to dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactory.java index f5bbdc8829..166ef8defd 100644 --- a/dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactory.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactory.java @@ -5,32 +5,31 @@ * * http://www.dspace.org/license/ */ -package org.dspace.workflow.factory; +package org.dspace.xmlworkflow.factory; import org.dspace.services.factory.DSpaceServicesFactory; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflow.WorkflowService; -import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; +import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService; import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; /** - * Abstract factory to get services for the workflow package, use WorkflowServiceFactory.getInstance() to retrieve an - * implementation + * Abstract factory to get services for the xmlworkflow package, use XmlWorkflowServiceFactory.getInstance() to + * retrieve an implementation * * @author kevinvandevelde at atmire.com */ -public abstract class WorkflowServiceFactory { +public abstract class XmlWorkflowServiceFactory { public abstract XmlWorkflowFactory getWorkflowFactory(); public abstract WorkflowRequirementsService getWorkflowRequirementsService(); - public abstract WorkflowService getWorkflowService(); + public abstract XmlWorkflowService getXmlWorkflowService(); public abstract ClaimedTaskService getClaimedTaskService(); @@ -42,10 +41,10 @@ public abstract class WorkflowServiceFactory { public abstract WorkflowItemRoleService getWorkflowItemRoleService(); - public abstract WorkflowItemService getWorkflowItemService(); + public abstract XmlWorkflowItemService getXmlWorkflowItemService(); - public static WorkflowServiceFactory getInstance() { + public static XmlWorkflowServiceFactory getInstance() { return DSpaceServicesFactory.getInstance().getServiceManager() - .getServiceByName("workflowServiceFactory", WorkflowServiceFactory.class); + .getServiceByName("workflowServiceFactory", XmlWorkflowServiceFactory.class); } } diff --git a/dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactoryImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactoryImpl.java similarity index 81% rename from dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactoryImpl.java rename to dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactoryImpl.java index a934819edf..8d8e9fe735 100644 --- a/dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactoryImpl.java @@ -5,17 +5,16 @@ * * http://www.dspace.org/license/ */ -package org.dspace.workflow.factory; +package org.dspace.xmlworkflow.factory; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflow.WorkflowService; -import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; +import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService; import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -24,14 +23,14 @@ import org.springframework.beans.factory.annotation.Autowired; * * @author kevinvandevelde at atmire.com */ -public class WorkflowServiceFactoryImpl extends WorkflowServiceFactory { +public class XmlWorkflowServiceFactoryImpl extends XmlWorkflowServiceFactory { @Autowired(required = true) private XmlWorkflowFactory workflowFactory; @Autowired(required = true) private WorkflowRequirementsService workflowRequirementsService; @Autowired(required = true) - private WorkflowService workflowService; + private XmlWorkflowService xmlWorkflowService; @Autowired(required = true) private ClaimedTaskService claimedTaskService; @Autowired(required = true) @@ -43,7 +42,7 @@ public class WorkflowServiceFactoryImpl extends WorkflowServiceFactory { @Autowired(required = true) private WorkflowItemRoleService workflowItemRoleService; @Autowired(required = true) - private WorkflowItemService workflowItemService; + private XmlWorkflowItemService xmlWorkflowItemService; @Override public XmlWorkflowFactory getWorkflowFactory() { @@ -56,8 +55,8 @@ public class WorkflowServiceFactoryImpl extends WorkflowServiceFactory { } @Override - public WorkflowService getWorkflowService() { - return workflowService; + public XmlWorkflowService getXmlWorkflowService() { + return xmlWorkflowService; } @Override @@ -86,7 +85,7 @@ public class WorkflowServiceFactoryImpl extends WorkflowServiceFactory { } @Override - public WorkflowItemService getWorkflowItemService() { - return workflowItemService; + public XmlWorkflowItemService getXmlWorkflowItemService() { + return xmlWorkflowItemService; } } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/migration/RestartWorkflow.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/migration/RestartWorkflow.java index 60e520eee0..7b15f020ce 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/migration/RestartWorkflow.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/migration/RestartWorkflow.java @@ -23,9 +23,9 @@ import org.dspace.core.LogManager; import org.dspace.eperson.EPerson; import org.dspace.eperson.factory.EPersonServiceFactory; import org.dspace.eperson.service.EPersonService; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowService; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.xmlworkflow.service.XmlWorkflowService; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * A utility class that will send all the worklfow items @@ -114,11 +114,11 @@ public class RestartWorkflow { System.out.println("Sending all workflow items back to the workspace"); - WorkflowServiceFactory workflowServiceFactory = WorkflowServiceFactory.getInstance(); - List workflowItems = workflowServiceFactory.getWorkflowItemService().findAll(context); - WorkflowService workflowService = workflowServiceFactory.getWorkflowService(); + XmlWorkflowServiceFactory workflowServiceFactory = XmlWorkflowServiceFactory.getInstance(); + List workflowItems = workflowServiceFactory.getXmlWorkflowItemService().findAll(context); + XmlWorkflowService workflowService = workflowServiceFactory.getXmlWorkflowService(); int i = 0; - for (WorkflowItem workflowItem : workflowItems) { + for (XmlWorkflowItem workflowItem : workflowItems) { System.out.println("Processing workflow item " + i + " of " + workflowItems.size()); System.out.println("Removing pooled tasks"); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/service/WorkflowRequirementsService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/service/WorkflowRequirementsService.java index ec102e2fca..29d29dbcda 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/service/WorkflowRequirementsService.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/service/WorkflowRequirementsService.java @@ -13,9 +13,9 @@ import java.sql.SQLException; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.Step; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * A class that contains utililty methods related to the workflow @@ -46,10 +46,10 @@ public interface WorkflowRequirementsService { * @throws AuthorizeException ... * @throws IOException ... */ - public void addClaimedUser(Context context, WorkflowItem wfi, Step step, EPerson user) + public void addClaimedUser(Context context, XmlWorkflowItem wfi, Step step, EPerson user) throws SQLException, AuthorizeException, IOException; - public void removeClaimedUser(Context context, WorkflowItem wfi, EPerson user, String stepID) + public void removeClaimedUser(Context context, XmlWorkflowItem wfi, EPerson user, String stepID) throws SQLException, IOException, WorkflowConfigurationException, AuthorizeException; /** @@ -62,8 +62,8 @@ public interface WorkflowRequirementsService { * @throws AuthorizeException ... * @throws SQLException ... */ - public void addFinishedUser(Context context, WorkflowItem wfi, EPerson user) + public void addFinishedUser(Context context, XmlWorkflowItem wfi, EPerson user) throws AuthorizeException, SQLException; - public void clearInProgressUsers(Context context, WorkflowItem wfi) throws AuthorizeException, SQLException; + public void clearInProgressUsers(Context context, XmlWorkflowItem wfi) throws AuthorizeException, SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/workflow/WorkflowService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/service/XmlWorkflowService.java similarity index 80% rename from dspace-api/src/main/java/org/dspace/workflow/WorkflowService.java rename to dspace-api/src/main/java/org/dspace/xmlworkflow/service/XmlWorkflowService.java index 62cb355dbe..af8554be8f 100644 --- a/dspace-api/src/main/java/org/dspace/workflow/WorkflowService.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/service/XmlWorkflowService.java @@ -5,7 +5,7 @@ * * http://www.dspace.org/license/ */ -package org.dspace.workflow; +package org.dspace.xmlworkflow.service; import java.io.IOException; import java.sql.SQLException; @@ -20,6 +20,7 @@ import org.dspace.content.WorkspaceItem; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; +import org.dspace.workflow.WorkflowException; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.Step; @@ -28,6 +29,7 @@ import org.dspace.xmlworkflow.state.actions.ActionResult; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.PoolTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * When an item is submitted and is somewhere in a workflow, it has a row in the @@ -40,7 +42,7 @@ import org.dspace.xmlworkflow.storedcomponents.PoolTask; * @author Ben Bosman (ben at atmire dot com) * @author Mark Diggory (markd at atmire dot com) */ -public interface WorkflowService { +public interface XmlWorkflowService { /** * startWorkflow() begins a workflow - in a single transaction do away with * the PersonalWorkspace entry and turn it into a WorkflowItem. @@ -54,7 +56,7 @@ public interface WorkflowService { * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. * @throws WorkflowException if workflow error */ - public WorkflowItem start(Context context, WorkspaceItem wsi) + public XmlWorkflowItem start(Context context, WorkspaceItem wsi) throws SQLException, AuthorizeException, IOException, WorkflowException; /** @@ -71,7 +73,7 @@ public interface WorkflowService { * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. * @throws WorkflowException if workflow error */ - public WorkflowItem startWithoutNotify(Context c, WorkspaceItem wsi) + public XmlWorkflowItem startWithoutNotify(Context c, WorkspaceItem wsi) throws SQLException, AuthorizeException, IOException, WorkflowException; /** @@ -88,7 +90,7 @@ public interface WorkflowService { * to perform a particular action. * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. */ - public WorkspaceItem abort(Context c, WorkflowItem wi, EPerson e) + public WorkspaceItem abort(Context c, XmlWorkflowItem wi, EPerson e) throws SQLException, AuthorizeException, IOException; /** @@ -102,10 +104,10 @@ public interface WorkflowService { * to perform a particular action. * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. */ - public void deleteWorkflowByWorkflowItem(Context c, WorkflowItem wi, EPerson e) + public void deleteWorkflowByWorkflowItem(Context c, XmlWorkflowItem wi, EPerson e) throws SQLException, AuthorizeException, IOException; - public WorkspaceItem sendWorkflowItemBackSubmission(Context c, WorkflowItem workflowItem, EPerson e, + public WorkspaceItem sendWorkflowItemBackSubmission(Context c, XmlWorkflowItem workflowItem, EPerson e, String provenance, String rejection_message) throws SQLException, AuthorizeException, IOException; @@ -136,37 +138,37 @@ public interface WorkflowService { public List getFlywayMigrationLocations(); - public void alertUsersOnTaskActivation(Context c, WorkflowItem wfi, String emailTemplate, List epa, + public void alertUsersOnTaskActivation(Context c, XmlWorkflowItem wfi, String emailTemplate, List epa, String... arguments) throws IOException, SQLException, MessagingException; public WorkflowActionConfig doState(Context c, EPerson user, HttpServletRequest request, int workflowItemId, Workflow workflow, WorkflowActionConfig currentActionConfig) - throws SQLException, AuthorizeException, IOException, MessagingException, WorkflowException; + throws SQLException, AuthorizeException, IOException, MessagingException, WorkflowException; public WorkflowActionConfig processOutcome(Context c, EPerson user, Workflow workflow, Step currentStep, WorkflowActionConfig currentActionConfig, ActionResult currentOutcome, - WorkflowItem wfi, boolean enteredNewStep) - throws IOException, AuthorizeException, SQLException, WorkflowException; + XmlWorkflowItem wfi, boolean enteredNewStep) + throws IOException, AuthorizeException, SQLException, WorkflowException; - public void deleteAllTasks(Context context, WorkflowItem wi) throws SQLException, AuthorizeException; + public void deleteAllTasks(Context context, XmlWorkflowItem wi) throws SQLException, AuthorizeException; - public void deleteAllPooledTasks(Context c, WorkflowItem wi) throws SQLException, AuthorizeException; + public void deleteAllPooledTasks(Context c, XmlWorkflowItem wi) throws SQLException, AuthorizeException; - public void deletePooledTask(Context context, WorkflowItem wi, PoolTask task) - throws SQLException, AuthorizeException; + public void deletePooledTask(Context context, XmlWorkflowItem wi, PoolTask task) + throws SQLException, AuthorizeException; - public void deleteClaimedTask(Context c, WorkflowItem wi, ClaimedTask task) - throws SQLException, AuthorizeException; + public void deleteClaimedTask(Context c, XmlWorkflowItem wi, ClaimedTask task) + throws SQLException, AuthorizeException; - public void createPoolTasks(Context context, WorkflowItem wi, RoleMembers assignees, Step step, + public void createPoolTasks(Context context, XmlWorkflowItem wi, RoleMembers assignees, Step step, WorkflowActionConfig action) - throws SQLException, AuthorizeException; + throws SQLException, AuthorizeException; - public void createOwnedTask(Context context, WorkflowItem wi, Step step, WorkflowActionConfig action, EPerson e) - throws SQLException, AuthorizeException; + public void createOwnedTask(Context context, XmlWorkflowItem wi, Step step, WorkflowActionConfig action, EPerson e) + throws SQLException, AuthorizeException; public void grantUserAllItemPolicies(Context context, Item item, EPerson epa, String actionType) - throws AuthorizeException, SQLException; + throws AuthorizeException, SQLException; public void removeUserItemPolicies(Context context, Item item, EPerson e) throws SQLException, AuthorizeException; diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Step.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Step.java index 24633ebc23..813bee1d89 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Step.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Step.java @@ -14,11 +14,11 @@ import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.dspace.core.Context; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.Role; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.annotation.Autowired; @@ -87,7 +87,7 @@ public class Step implements BeanNameAware { } - public boolean isValidStep(Context context, WorkflowItem wfi) + public boolean isValidStep(Context context, XmlWorkflowItem wfi) throws WorkflowConfigurationException, SQLException { //Check if our next step has a UI, if not then the step is valid, no need for a group return !(getUserSelectionMethod() == null || getUserSelectionMethod() @@ -125,7 +125,7 @@ public class Step implements BeanNameAware { * @return if enough users have finished this task * @throws SQLException An exception that provides information on a database access error or other errors. */ - public boolean isFinished(Context c, WorkflowItem wfi) throws SQLException { + public boolean isFinished(Context c, XmlWorkflowItem wfi) throws SQLException { return inProgressUserService.getNumberOfFinishedUsers(c, wfi) == requiredUsers; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Workflow.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Workflow.java index 5e35eabbe5..935f3e0cbe 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Workflow.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/Workflow.java @@ -13,10 +13,10 @@ import java.util.List; import java.util.Map; import org.dspace.core.Context; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.Role; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.actions.ActionResult; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.annotation.Autowired; @@ -55,7 +55,7 @@ public class Workflow implements BeanNameAware { throw new WorkflowConfigurationException("Step definition not found for: " + stepID); } - public Step getNextStep(Context context, WorkflowItem wfi, Step currentStep, int outcome) + public Step getNextStep(Context context, XmlWorkflowItem wfi, Step currentStep, int outcome) throws WorkflowConfigurationException, SQLException { Step nextStep = currentStep.getNextStep(outcome); if (nextStep != null) { diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/Action.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/Action.java index c2fcf988e3..c0c05b1745 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/Action.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/Action.java @@ -16,10 +16,10 @@ import javax.servlet.http.HttpServletRequest; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.workflow.WorkflowException; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.Step; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * This abstract class represents an api action @@ -38,10 +38,10 @@ public abstract class Action { private WorkflowActionConfig parent; private static final String ERROR_FIELDS_ATTRIBUTE = "dspace.workflow.error_fields"; - public abstract void activate(Context c, WorkflowItem wf) + public abstract void activate(Context c, XmlWorkflowItem wf) throws SQLException, IOException, AuthorizeException, WorkflowException; - public abstract ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) + public abstract ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException, WorkflowException; /** @@ -76,12 +76,12 @@ public abstract class Action { return "Step: " + getParent().getStep().getId() + " - action:" + getParent().getId(); } - public void alertUsersOnActivation(Context c, WorkflowItem wfi, RoleMembers members) + public void alertUsersOnActivation(Context c, XmlWorkflowItem wfi, RoleMembers members) throws SQLException, IOException { } - public abstract boolean isAuthorized(Context context, HttpServletRequest request, WorkflowItem wfi) + public abstract boolean isAuthorized(Context context, HttpServletRequest request, XmlWorkflowItem wfi) throws SQLException, AuthorizeException, IOException, WorkflowConfigurationException; diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/AcceptEditRejectAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/AcceptEditRejectAction.java index 621e7678f1..743d00b2b6 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/AcceptEditRejectAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/AcceptEditRejectAction.java @@ -18,10 +18,10 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.content.DCDate; import org.dspace.content.MetadataSchemaEnum; import org.dspace.core.Context; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Processing class of an action that allows users to @@ -41,12 +41,12 @@ public class AcceptEditRejectAction extends ProcessingAction { //TODO: rename to AcceptAndEditMetadataAction @Override - public void activate(Context c, WorkflowItem wf) { + public void activate(Context c, XmlWorkflowItem wf) { } @Override - public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { if (super.isOptionInParam(request)) { switch (Util.getSubmitButton(request, SUBMIT_CANCEL)) { @@ -72,7 +72,7 @@ public class AcceptEditRejectAction extends ProcessingAction { return options; } - public ActionResult processAccept(Context c, WorkflowItem wfi) + public ActionResult processAccept(Context c, XmlWorkflowItem wfi) throws SQLException, AuthorizeException { //Delete the tasks addApprovedProvenance(c, wfi); @@ -80,7 +80,7 @@ public class AcceptEditRejectAction extends ProcessingAction { return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); } - public ActionResult processRejectPage(Context c, WorkflowItem wfi, HttpServletRequest request) + public ActionResult processRejectPage(Context c, XmlWorkflowItem wfi, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { String reason = request.getParameter("reason"); if (reason == null || 0 == reason.trim().length()) { @@ -90,16 +90,16 @@ public class AcceptEditRejectAction extends ProcessingAction { // We have pressed reject, so remove the task the user has & put it back // to a workspace item - WorkflowServiceFactory.getInstance().getWorkflowService().sendWorkflowItemBackSubmission(c, wfi, + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService().sendWorkflowItemBackSubmission(c, wfi, c.getCurrentUser(), this.getProvenanceStartId(), reason); return new ActionResult(ActionResult.TYPE.TYPE_SUBMISSION_PAGE); } - public ActionResult processSubmitterIsDeletedPage(Context c, WorkflowItem wfi, HttpServletRequest request) + public ActionResult processSubmitterIsDeletedPage(Context c, XmlWorkflowItem wfi, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { if (request.getParameter("submit_delete") != null) { - WorkflowServiceFactory.getInstance().getWorkflowService() + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() .deleteWorkflowByWorkflowItem(c, wfi, c.getCurrentUser()); // Delete and send user back to myDspace page return new ActionResult(ActionResult.TYPE.TYPE_SUBMISSION_PAGE); @@ -112,12 +112,12 @@ public class AcceptEditRejectAction extends ProcessingAction { } } - private void addApprovedProvenance(Context c, WorkflowItem wfi) throws SQLException, AuthorizeException { + private void addApprovedProvenance(Context c, XmlWorkflowItem wfi) throws SQLException, AuthorizeException { //Add the provenance for the accept String now = DCDate.getCurrent().toString(); // Get user's name + email address - String usersName = WorkflowServiceFactory.getInstance().getWorkflowService() + String usersName = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() .getEPersonName(c.getCurrentUser()); String provDescription = getProvenanceStartId() + " Approved for entry into archive by " diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/FinalEditAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/FinalEditAction.java index 1a35d90d6a..3c4e0ffc1d 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/FinalEditAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/FinalEditAction.java @@ -17,10 +17,10 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.content.DCDate; import org.dspace.content.MetadataSchemaEnum; import org.dspace.core.Context; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Processing class of an action that allows users to @@ -36,17 +36,17 @@ public class FinalEditAction extends ProcessingAction { private static final String SUBMIT_APPROVE = "submit_approve"; @Override - public void activate(Context c, WorkflowItem wf) { + public void activate(Context c, XmlWorkflowItem wf) { } @Override - public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException { return processMainPage(c, wfi, request); } - public ActionResult processMainPage(Context c, WorkflowItem wfi, HttpServletRequest request) + public ActionResult processMainPage(Context c, XmlWorkflowItem wfi, HttpServletRequest request) throws SQLException, AuthorizeException { if (super.isOptionInParam(request)) { switch (Util.getSubmitButton(request, SUBMIT_CANCEL)) { @@ -70,12 +70,12 @@ public class FinalEditAction extends ProcessingAction { return options; } - private void addApprovedProvenance(Context c, WorkflowItem wfi) throws SQLException, AuthorizeException { + private void addApprovedProvenance(Context c, XmlWorkflowItem wfi) throws SQLException, AuthorizeException { //Add the provenance for the accept String now = DCDate.getCurrent().toString(); // Get user's name + email address - String usersName = WorkflowServiceFactory.getInstance().getWorkflowService() + String usersName = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() .getEPersonName(c.getCurrentUser()); String provDescription = getProvenanceStartId() + " Approved for entry into archive by " diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ProcessingAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ProcessingAction.java index 7ae5c5e350..76e5cb5e9f 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ProcessingAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ProcessingAction.java @@ -12,9 +12,9 @@ import javax.servlet.http.HttpServletRequest; import org.dspace.content.service.ItemService; import org.dspace.core.Context; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.state.actions.Action; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.springframework.beans.factory.annotation.Autowired; @@ -38,7 +38,7 @@ public abstract class ProcessingAction extends Action { public static final String SUBMIT_CANCEL = "submit_cancel"; @Override - public boolean isAuthorized(Context context, HttpServletRequest request, WorkflowItem wfi) throws SQLException { + public boolean isAuthorized(Context context, HttpServletRequest request, XmlWorkflowItem wfi) throws SQLException { ClaimedTask task = null; if (context.getCurrentUser() != null) { task = claimedTaskService.findByWorkflowIdAndEPerson(context, wfi, context.getCurrentUser()); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ReviewAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ReviewAction.java index 11fe8e574e..8474757be6 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ReviewAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ReviewAction.java @@ -18,10 +18,10 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.content.DCDate; import org.dspace.content.MetadataSchemaEnum; import org.dspace.core.Context; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Processing class of an accept/reject action @@ -42,12 +42,12 @@ public class ReviewAction extends ProcessingAction { @Override - public void activate(Context c, WorkflowItem wfItem) { + public void activate(Context c, XmlWorkflowItem wfItem) { } @Override - public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { if (super.isOptionInParam(request)) { switch (Util.getSubmitButton(request, SUBMIT_CANCEL)) { @@ -72,18 +72,18 @@ public class ReviewAction extends ProcessingAction { return options; } - public ActionResult processAccept(Context c, WorkflowItem wfi) throws SQLException, AuthorizeException { + public ActionResult processAccept(Context c, XmlWorkflowItem wfi) throws SQLException, AuthorizeException { //Delete the tasks addApprovedProvenance(c, wfi); return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); } - private void addApprovedProvenance(Context c, WorkflowItem wfi) throws SQLException, AuthorizeException { + private void addApprovedProvenance(Context c, XmlWorkflowItem wfi) throws SQLException, AuthorizeException { //Add the provenance for the accept String now = DCDate.getCurrent().toString(); // Get user's name + email address - String usersName = WorkflowServiceFactory.getInstance().getWorkflowService() + String usersName = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() .getEPersonName(c.getCurrentUser()); String provDescription = getProvenanceStartId() + " Approved for entry into archive by " @@ -95,7 +95,7 @@ public class ReviewAction extends ProcessingAction { itemService.update(c, wfi.getItem()); } - public ActionResult processRejectPage(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult processRejectPage(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { String reason = request.getParameter("reason"); if (reason == null || 0 == reason.trim().length()) { @@ -105,7 +105,7 @@ public class ReviewAction extends ProcessingAction { } //We have pressed reject, so remove the task the user has & put it back to a workspace item - WorkflowServiceFactory.getInstance().getWorkflowService() + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() .sendWorkflowItemBackSubmission(c, wfi, c.getCurrentUser(), this.getProvenanceStartId(), reason); @@ -113,10 +113,10 @@ public class ReviewAction extends ProcessingAction { return new ActionResult(ActionResult.TYPE.TYPE_SUBMISSION_PAGE); } - public ActionResult processSubmitterIsDeletedPage(Context c, WorkflowItem wfi, HttpServletRequest request) + public ActionResult processSubmitterIsDeletedPage(Context c, XmlWorkflowItem wfi, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { if (request.getParameter("submit_delete") != null) { - WorkflowServiceFactory.getInstance().getWorkflowService() + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() .deleteWorkflowByWorkflowItem(c, wfi, c.getCurrentUser()); // Delete and send user back to myDspace page return new ActionResult(ActionResult.TYPE.TYPE_SUBMISSION_PAGE); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreEvaluationAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreEvaluationAction.java index 94ac8266b6..a834641111 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreEvaluationAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreEvaluationAction.java @@ -18,11 +18,11 @@ import org.dspace.content.Item; import org.dspace.content.MetadataSchemaEnum; import org.dspace.content.MetadataValue; import org.dspace.core.Context; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Processing class for the score evaluation action @@ -40,12 +40,12 @@ public class ScoreEvaluationAction extends ProcessingAction { private int minimumAcceptanceScore; @Override - public void activate(Context c, WorkflowItem wf) { + public void activate(Context c, XmlWorkflowItem wf) { } @Override - public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { boolean hasPassed = false; //Retrieve all our scores from the metadata & add em up @@ -73,7 +73,7 @@ public class ScoreEvaluationAction extends ProcessingAction { return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); } else { //We haven't passed, reject our item - WorkflowServiceFactory.getInstance().getWorkflowService() + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() .sendWorkflowItemBackSubmission(c, wfi, c.getCurrentUser(), this.getProvenanceStartId(), "The item was reject due to a bad review score."); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java index 93c320d185..c28fe2d93e 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java @@ -15,10 +15,10 @@ import javax.servlet.http.HttpServletRequest; import org.dspace.app.util.Util; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * This action will allow multiple users to rate a certain item @@ -35,12 +35,12 @@ public class ScoreReviewAction extends ProcessingAction { private static final String SUBMIT_SCORE = "submit_score"; @Override - public void activate(Context c, WorkflowItem wf) { + public void activate(Context c, XmlWorkflowItem wf) { } @Override - public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException { if (request.getParameter(SUBMIT_SCORE) != null) { int score = Util.getIntParameter(request, "score"); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SelectReviewerAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SelectReviewerAction.java index 7651a8bf58..16a8777275 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SelectReviewerAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SelectReviewerAction.java @@ -18,11 +18,11 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.service.EPersonService; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.Role; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; import org.springframework.beans.factory.annotation.Autowired; @@ -54,12 +54,12 @@ public class SelectReviewerAction extends ProcessingAction { private WorkflowItemRoleService workflowItemRoleService; @Override - public void activate(Context c, WorkflowItem wf) { + public void activate(Context c, XmlWorkflowItem wf) { } @Override - public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException { String submitButton = Util.getSubmitButton(request, SUBMIT_CANCEL); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java index c3e251ed4b..9ef554821d 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java @@ -18,10 +18,10 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.content.DCDate; import org.dspace.content.MetadataSchemaEnum; import org.dspace.core.Context; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Processing class of an action where a single user has @@ -46,12 +46,12 @@ public class SingleUserReviewAction extends ProcessingAction { protected static final String SUBMIT_DECLINE_TASK = "submit_decline_task"; @Override - public void activate(Context c, WorkflowItem wfItem) { + public void activate(Context c, XmlWorkflowItem wfItem) { } @Override - public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { int page = Util.getIntParameter(request, "page"); @@ -76,7 +76,7 @@ public class SingleUserReviewAction extends ProcessingAction { return options; } - public ActionResult processMainPage(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult processMainPage(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException { if (request.getParameter(SUBMIT_APPROVE) != null) { //Delete the tasks @@ -101,12 +101,12 @@ public class SingleUserReviewAction extends ProcessingAction { } } - private void addApprovedProvenance(Context c, WorkflowItem wfi) throws SQLException, AuthorizeException { + private void addApprovedProvenance(Context c, XmlWorkflowItem wfi) throws SQLException, AuthorizeException { //Add the provenance for the accept String now = DCDate.getCurrent().toString(); // Get user's name + email address - String usersName = WorkflowServiceFactory.getInstance().getWorkflowService() + String usersName = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() .getEPersonName(c.getCurrentUser()); String provDescription = getProvenanceStartId() + " Approved for entry into archive by " @@ -118,7 +118,7 @@ public class SingleUserReviewAction extends ProcessingAction { itemService.update(c, wfi.getItem()); } - public ActionResult processRejectPage(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult processRejectPage(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { if (request.getParameter("submit_reject") != null) { String reason = request.getParameter("reason"); @@ -129,7 +129,7 @@ public class SingleUserReviewAction extends ProcessingAction { } //We have pressed reject, so remove the task the user has & put it back to a workspace item - WorkflowServiceFactory.getInstance().getWorkflowService() + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() .sendWorkflowItemBackSubmission(c, wfi, c.getCurrentUser(), this.getProvenanceStartId(), reason); @@ -143,10 +143,10 @@ public class SingleUserReviewAction extends ProcessingAction { } } - public ActionResult processSubmitterIsDeletedPage(Context c, WorkflowItem wfi, HttpServletRequest request) + public ActionResult processSubmitterIsDeletedPage(Context c, XmlWorkflowItem wfi, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { if (request.getParameter("submit_delete") != null) { - WorkflowServiceFactory.getInstance().getWorkflowService() + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() .deleteWorkflowByWorkflowItem(c, wfi, c.getCurrentUser()); // Delete and send user back to myDspace page return new ActionResult(ActionResult.TYPE.TYPE_SUBMISSION_PAGE); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignAction.java index b4a93edb59..e837a8a893 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignAction.java @@ -13,11 +13,11 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import org.dspace.core.Context; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * @author Bram De Schouwer (bram.deschouwer at dot com) @@ -28,11 +28,11 @@ import org.dspace.xmlworkflow.state.actions.ActionResult; public class AssignAction extends UserSelectionAction { @Override - public void activate(Context c, WorkflowItem wfItem) { + public void activate(Context c, XmlWorkflowItem wfItem) { } @Override - public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) { + public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) { return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); } @@ -45,16 +45,16 @@ public class AssignAction extends UserSelectionAction { } @Override - public boolean isFinished(WorkflowItem wfi) { + public boolean isFinished(XmlWorkflowItem wfi) { return false; } @Override - public void regenerateTasks(Context c, WorkflowItem wfi, RoleMembers roleMembers) throws SQLException { + public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) throws SQLException { } @Override - public boolean isValidUserSelection(Context context, WorkflowItem wfi, boolean hasUI) + public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) throws WorkflowConfigurationException, SQLException { return false; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignOriginalSubmitterAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignOriginalSubmitterAction.java index b979ab6046..3c8d85997a 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignOriginalSubmitterAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AssignOriginalSubmitterAction.java @@ -20,15 +20,15 @@ import org.dspace.core.Context; import org.dspace.core.LogManager; import org.dspace.eperson.EPerson; import org.dspace.workflow.WorkflowException; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowService; -import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; +import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.springframework.beans.factory.annotation.Autowired; /** @@ -46,17 +46,17 @@ public class AssignOriginalSubmitterAction extends UserSelectionAction { protected WorkflowRequirementsService workflowRequirementsService; @Override - public boolean isFinished(WorkflowItem wfi) { + public boolean isFinished(XmlWorkflowItem wfi) { return false; } @Override - public void regenerateTasks(Context c, WorkflowItem wfi, RoleMembers roleMembers) throws SQLException { + public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) throws SQLException { } @Override - public boolean isValidUserSelection(Context context, WorkflowItem wfi, boolean hasUI) + public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) throws WorkflowConfigurationException, SQLException { return wfi.getSubmitter() != null; } @@ -67,24 +67,24 @@ public class AssignOriginalSubmitterAction extends UserSelectionAction { } @Override - public void activate(Context c, WorkflowItem wf) throws SQLException, IOException { + public void activate(Context c, XmlWorkflowItem wf) throws SQLException, IOException { } @Override - public void alertUsersOnActivation(Context c, WorkflowItem wfi, RoleMembers roleMembers) + public void alertUsersOnActivation(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) throws IOException, SQLException { if (wfi.getSubmitter() != null) { try { - WorkflowService workflowService = WorkflowServiceFactory.getInstance().getWorkflowService(); - workflowService.alertUsersOnTaskActivation(c, wfi, "submit_task", Arrays.asList(wfi.getSubmitter()), + XmlWorkflowService xmlWorkflowService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); + xmlWorkflowService.alertUsersOnTaskActivation(c, wfi, "submit_task", Arrays.asList(wfi.getSubmitter()), //The arguments wfi.getItem().getName(), wfi.getCollection().getName(), wfi.getSubmitter().getFullName(), //TODO: message "New task available.", - workflowService.getMyDSpaceLink() + xmlWorkflowService.getMyDSpaceLink() ); } catch (MessagingException e) { log.info(LogManager.getHeader(c, "error emailing user(s) for claimed task", @@ -95,7 +95,7 @@ public class AssignOriginalSubmitterAction extends UserSelectionAction { @Override - public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException, WorkflowException { EPerson submitter = wfi.getSubmitter(); WorkflowActionConfig nextAction = getParent().getStep().getNextAction(this.getParent()); @@ -133,11 +133,11 @@ public class AssignOriginalSubmitterAction extends UserSelectionAction { * @throws AuthorizeException ... * @throws IOException ... */ - protected void createTaskForEPerson(Context c, WorkflowItem wfi, Step step, WorkflowActionConfig actionConfig, + protected void createTaskForEPerson(Context c, XmlWorkflowItem wfi, Step step, WorkflowActionConfig actionConfig, EPerson user) throws SQLException, AuthorizeException, IOException { if (claimedTaskService.find(c, wfi, step.getId(), actionConfig.getId()) != null) { workflowRequirementsService.addClaimedUser(c, wfi, step, c.getCurrentUser()); - WorkflowServiceFactory.getInstance().getWorkflowService() + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() .createOwnedTask(c, wfi, step, actionConfig, user); } } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AutoAssignAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AutoAssignAction.java index f46a3cc2bd..3f87c26029 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AutoAssignAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/AutoAssignAction.java @@ -19,16 +19,16 @@ import org.dspace.core.Context; import org.dspace.core.LogManager; import org.dspace.eperson.EPerson; import org.dspace.eperson.service.GroupService; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.Role; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.springframework.beans.factory.annotation.Autowired; /** @@ -51,12 +51,12 @@ public class AutoAssignAction extends UserSelectionAction { protected WorkflowRequirementsService workflowRequirementsService; @Override - public void activate(Context c, WorkflowItem wfItem) { + public void activate(Context c, XmlWorkflowItem wfItem) { } @Override - public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { try { Role role = getParent().getStep().getRole(); @@ -124,27 +124,27 @@ public class AutoAssignAction extends UserSelectionAction { * @throws AuthorizeException ... * @throws IOException ... */ - protected void createTaskForEPerson(Context c, WorkflowItem wfi, Step step, WorkflowActionConfig actionConfig, + protected void createTaskForEPerson(Context c, XmlWorkflowItem wfi, Step step, WorkflowActionConfig actionConfig, EPerson user) throws SQLException, AuthorizeException, IOException { if (claimedTaskService.find(c, wfi, step.getId(), actionConfig.getId()) != null) { workflowRequirementsService.addClaimedUser(c, wfi, step, c.getCurrentUser()); - WorkflowServiceFactory.getInstance().getWorkflowService() + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() .createOwnedTask(c, wfi, step, actionConfig, user); } } @Override - public boolean isFinished(WorkflowItem wfi) { + public boolean isFinished(XmlWorkflowItem wfi) { return true; } @Override - public void regenerateTasks(Context c, WorkflowItem wfi, RoleMembers roleMembers) throws SQLException { + public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) throws SQLException { } @Override - public boolean isValidUserSelection(Context context, WorkflowItem wfi, boolean hasUI) + public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) throws WorkflowConfigurationException, SQLException { //This is an automatic assign action, it can never have a user interface Role role = getParent().getStep().getRole(); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/ClaimAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/ClaimAction.java index 9ea7261d59..744bf69136 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/ClaimAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/ClaimAction.java @@ -20,14 +20,14 @@ import org.dspace.core.LogManager; import org.dspace.eperson.EPerson; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowService; -import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.Role; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Processing class for an action where x number of users @@ -43,14 +43,14 @@ public class ClaimAction extends UserSelectionAction { = DSpaceServicesFactory.getInstance().getConfigurationService(); @Override - public void activate(Context context, WorkflowItem wfItem) throws SQLException, IOException, AuthorizeException { + public void activate(Context context, XmlWorkflowItem wfItem) throws SQLException, IOException, AuthorizeException { Step owningStep = getParent().getStep(); RoleMembers allroleMembers = getParent().getStep().getRole().getMembers(context, wfItem); // Create pooled tasks for each member of our group if (allroleMembers != null && (allroleMembers.getGroups().size() > 0 || allroleMembers.getEPersons() .size() > 0)) { - WorkflowServiceFactory.getInstance().getWorkflowService() + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() .createPoolTasks(context, wfItem, allroleMembers, owningStep, getParent()); alertUsersOnActivation(context, wfItem, allroleMembers); } else { @@ -63,10 +63,10 @@ public class ClaimAction extends UserSelectionAction { } @Override - public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) + public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { // accept task, or accepting multiple tasks - WorkflowServiceFactory.getInstance().getWorkflowRequirementsService().addClaimedUser(c, wfi, step, + XmlWorkflowServiceFactory.getInstance().getWorkflowRequirementsService().addClaimedUser(c, wfi, step, c.getCurrentUser()); return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); } @@ -77,7 +77,7 @@ public class ClaimAction extends UserSelectionAction { } @Override - public void alertUsersOnActivation(Context c, WorkflowItem wfi, RoleMembers roleMembers) + public void alertUsersOnActivation(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) throws IOException, SQLException { try { EPerson ep = wfi.getSubmitter(); @@ -85,15 +85,15 @@ public class ClaimAction extends UserSelectionAction { if (ep != null) { submitterName = ep.getFullName(); } - WorkflowService workflowService = WorkflowServiceFactory.getInstance().getWorkflowService(); - workflowService.alertUsersOnTaskActivation(c, wfi, "submit_task", roleMembers.getAllUniqueMembers(c), + XmlWorkflowService xmlWorkflowService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); + xmlWorkflowService.alertUsersOnTaskActivation(c, wfi, "submit_task", roleMembers.getAllUniqueMembers(c), //The arguments wfi.getItem().getName(), wfi.getCollection().getName(), submitterName, //TODO: message "New task available.", - workflowService.getMyDSpaceLink() + xmlWorkflowService.getMyDSpaceLink() ); } catch (MessagingException e) { log.info(LogManager.getHeader(c, "error emailing user(s) for claimed task", @@ -102,11 +102,11 @@ public class ClaimAction extends UserSelectionAction { } @Override - public void regenerateTasks(Context c, WorkflowItem wfi, RoleMembers roleMembers) + public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) throws SQLException, AuthorizeException, IOException { if (roleMembers != null && (roleMembers.getEPersons().size() > 0 || roleMembers.getGroups().size() > 0)) { //Create task for the users left - WorkflowServiceFactory.getInstance().getWorkflowService() + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService() .createPoolTasks(c, wfi, roleMembers, getParent().getStep(), getParent()); if (configurationService.getBooleanProperty("workflow.notify.returned.tasks", true)) { alertUsersOnActivation(c, wfi, roleMembers); @@ -121,12 +121,12 @@ public class ClaimAction extends UserSelectionAction { } @Override - public boolean isFinished(WorkflowItem wfi) { + public boolean isFinished(XmlWorkflowItem wfi) { return false; } @Override - public boolean isValidUserSelection(Context context, WorkflowItem wfi, boolean hasUI) + public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) throws WorkflowConfigurationException, SQLException { //A user claim action always needs to have a UI, since somebody needs to be able to claim it if (hasUI) { diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/InheritUsersAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/InheritUsersAction.java index 422c03218b..1ffce1afdb 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/InheritUsersAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/InheritUsersAction.java @@ -13,11 +13,11 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import org.dspace.core.Context; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * A user selection action that inherits user @@ -31,11 +31,11 @@ import org.dspace.xmlworkflow.state.actions.ActionResult; public class InheritUsersAction extends UserSelectionAction { @Override - public void activate(Context c, WorkflowItem wfItem) { + public void activate(Context c, XmlWorkflowItem wfItem) { } @Override - public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) { + public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) { return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); } @@ -45,16 +45,16 @@ public class InheritUsersAction extends UserSelectionAction { } @Override - public boolean isFinished(WorkflowItem wfi) { + public boolean isFinished(XmlWorkflowItem wfi) { return false; } @Override - public void regenerateTasks(Context c, WorkflowItem wfi, RoleMembers roleMembers) throws SQLException { + public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) throws SQLException { } @Override - public boolean isValidUserSelection(Context context, WorkflowItem wfi, boolean hasUI) + public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) throws WorkflowConfigurationException, SQLException { return false; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/NoUserSelectionAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/NoUserSelectionAction.java index 98e1ede2a4..d23a98cedb 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/NoUserSelectionAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/NoUserSelectionAction.java @@ -12,10 +12,10 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import org.dspace.core.Context; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionResult; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * A user selection action that does not assign any users @@ -27,16 +27,16 @@ import org.dspace.xmlworkflow.state.actions.ActionResult; */ public class NoUserSelectionAction extends UserSelectionAction { @Override - public boolean isFinished(WorkflowItem wfi) { + public boolean isFinished(XmlWorkflowItem wfi) { return true; } @Override - public void regenerateTasks(Context c, WorkflowItem wfi, RoleMembers roleMembers) { + public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) { } @Override - public boolean isValidUserSelection(Context context, WorkflowItem wfi, boolean hasUI) { + public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) { return true; } @@ -46,11 +46,11 @@ public class NoUserSelectionAction extends UserSelectionAction { } @Override - public void activate(Context c, WorkflowItem wf) { + public void activate(Context c, XmlWorkflowItem wf) { } @Override - public ActionResult execute(Context c, WorkflowItem wfi, Step step, HttpServletRequest request) { + public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) { return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE); } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/UserSelectionAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/UserSelectionAction.java index 0896700eb2..bbeb7cd173 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/UserSelectionAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/userassignment/UserSelectionAction.java @@ -14,11 +14,11 @@ import javax.servlet.http.HttpServletRequest; import org.apache.logging.log4j.Logger; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.RoleMembers; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.actions.Action; import org.dspace.xmlworkflow.storedcomponents.PoolTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; @@ -38,7 +38,7 @@ public abstract class UserSelectionAction extends Action { protected Logger log = org.apache.logging.log4j.LogManager.getLogger(UserSelectionAction.class); - public abstract boolean isFinished(WorkflowItem wfi); + public abstract boolean isFinished(XmlWorkflowItem wfi); @Autowired(required = true) protected ClaimedTaskService claimedTaskService; @@ -48,7 +48,7 @@ public abstract class UserSelectionAction extends Action { protected WorkflowItemRoleService workflowItemRoleService; @Override - public boolean isAuthorized(Context context, HttpServletRequest request, WorkflowItem wfi) + public boolean isAuthorized(Context context, HttpServletRequest request, XmlWorkflowItem wfi) throws SQLException, AuthorizeException, IOException, WorkflowConfigurationException { PoolTask task = null; if (context.getCurrentUser() != null) { @@ -72,7 +72,7 @@ public abstract class UserSelectionAction extends Action { * @throws SQLException An exception that provides information on a database access error or other errors. * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. */ - public abstract void regenerateTasks(Context c, WorkflowItem wfi, RoleMembers roleMembers) + public abstract void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) throws SQLException, AuthorizeException, IOException; /** @@ -87,7 +87,7 @@ public abstract class UserSelectionAction extends Action { * @throws SQLException An exception that provides information on a database access error or * other errors. */ - public abstract boolean isValidUserSelection(Context context, WorkflowItem wfi, boolean hasUI) + public abstract boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) throws WorkflowConfigurationException, SQLException; /** diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTask.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTask.java index 3dd087289f..8882055f82 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTask.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTask.java @@ -21,7 +21,6 @@ import javax.persistence.Table; import org.dspace.core.Context; import org.dspace.core.ReloadableEntity; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; /** * Claimed task representing the database representation of an action claimed by an eperson @@ -43,7 +42,7 @@ public class ClaimedTask implements ReloadableEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "workflowitem_id") - private WorkflowItem workflowItem; + private XmlWorkflowItem workflowItem; // @Column(name = "workflow_id") // @Lob @@ -84,11 +83,11 @@ public class ClaimedTask implements ReloadableEntity { return owner; } - public void setWorkflowItem(WorkflowItem workflowItem) { + public void setWorkflowItem(XmlWorkflowItem workflowItem) { this.workflowItem = workflowItem; } - public WorkflowItem getWorkflowItem() { + public XmlWorkflowItem getWorkflowItem() { return workflowItem; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTaskServiceImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTaskServiceImpl.java index 22497705fa..4bed9cdbf0 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTaskServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/ClaimedTaskServiceImpl.java @@ -16,7 +16,6 @@ import org.apache.commons.collections4.CollectionUtils; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.ClaimedTaskDAO; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.springframework.beans.factory.annotation.Autowired; @@ -72,12 +71,12 @@ public class ClaimedTaskServiceImpl implements ClaimedTaskService { } @Override - public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException { + public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException { return claimedTaskDAO.findByWorkflowItem(context, workflowItem); } @Override - public ClaimedTask findByWorkflowIdAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) + public ClaimedTask findByWorkflowIdAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) throws SQLException { return claimedTaskDAO.findByWorkflowItemAndEPerson(context, workflowItem, ePerson); } @@ -88,25 +87,25 @@ public class ClaimedTaskServiceImpl implements ClaimedTaskService { } @Override - public List find(Context context, WorkflowItem workflowItem, String stepID) throws SQLException { + public List find(Context context, XmlWorkflowItem workflowItem, String stepID) throws SQLException { return claimedTaskDAO.findByWorkflowItemAndStepId(context, workflowItem, stepID); } @Override - public ClaimedTask find(Context context, EPerson ePerson, WorkflowItem workflowItem, String stepID, + public ClaimedTask find(Context context, EPerson ePerson, XmlWorkflowItem workflowItem, String stepID, String actionID) throws SQLException { return claimedTaskDAO .findByEPersonAndWorkflowItemAndStepIdAndActionId(context, ePerson, workflowItem, stepID, actionID); } @Override - public List find(Context context, WorkflowItem workflowItem, String stepID, String actionID) + public List find(Context context, XmlWorkflowItem workflowItem, String stepID, String actionID) throws SQLException { return claimedTaskDAO.findByWorkflowItemAndStepIdAndActionId(context, workflowItem, stepID, actionID); } @Override - public List find(Context context, WorkflowItem workflowItem) throws SQLException { + public List find(Context context, XmlWorkflowItem workflowItem) throws SQLException { return claimedTaskDAO.findByWorkflowItem(context, workflowItem); } @@ -116,7 +115,7 @@ public class ClaimedTaskServiceImpl implements ClaimedTaskService { } @Override - public void deleteByWorkflowItem(Context context, WorkflowItem workflowItem) + public void deleteByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException, AuthorizeException { List claimedTasks = findByWorkflowItem(context, workflowItem); //Use an iterator to remove the tasks ! diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUser.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUser.java index 2bb59c378d..5cd714345e 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUser.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUser.java @@ -21,7 +21,6 @@ import javax.persistence.Table; import org.dspace.core.Context; import org.dspace.core.ReloadableEntity; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; /** * Claimed task representing the database representation of an action claimed by an eperson @@ -47,7 +46,7 @@ public class InProgressUser implements ReloadableEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "workflowitem_id") - private WorkflowItem workflowItem; + private XmlWorkflowItem workflowItem; @Column(name = "finished") private boolean finished = false; @@ -72,11 +71,11 @@ public class InProgressUser implements ReloadableEntity { return this.ePerson; } - public void setWorkflowItem(WorkflowItem workflowItem) { + public void setWorkflowItem(XmlWorkflowItem workflowItem) { this.workflowItem = workflowItem; } - public WorkflowItem getWorkflowItem() { + public XmlWorkflowItem getWorkflowItem() { return this.workflowItem; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUserServiceImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUserServiceImpl.java index b88fd5d4f3..a2b5e718eb 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUserServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/InProgressUserServiceImpl.java @@ -15,7 +15,6 @@ import org.apache.commons.collections4.CollectionUtils; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.InProgressUserDAO; import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService; import org.springframework.beans.factory.annotation.Autowired; @@ -37,7 +36,7 @@ public class InProgressUserServiceImpl implements InProgressUserService { } @Override - public InProgressUser findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) + public InProgressUser findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) throws SQLException { return inProgressUserDAO.findByWorkflowItemAndEPerson(context, workflowItem, ePerson); } @@ -48,17 +47,17 @@ public class InProgressUserServiceImpl implements InProgressUserService { } @Override - public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException { + public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException { return inProgressUserDAO.findByWorkflowItem(context, workflowItem); } @Override - public int getNumberOfInProgressUsers(Context context, WorkflowItem workflowItem) throws SQLException { + public int getNumberOfInProgressUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException { return inProgressUserDAO.countInProgressUsers(context, workflowItem); } @Override - public int getNumberOfFinishedUsers(Context context, WorkflowItem workflowItem) throws SQLException { + public int getNumberOfFinishedUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException { return inProgressUserDAO.countFinishedUsers(context, workflowItem); } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTask.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTask.java index d7e1e360f1..2a87de51cb 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTask.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTask.java @@ -23,7 +23,6 @@ import org.dspace.core.Context; import org.dspace.core.ReloadableEntity; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; -import org.dspace.workflow.WorkflowItem; /** * Pool task representing the database representation of a pool task for a step and an eperson @@ -45,7 +44,7 @@ public class PoolTask implements ReloadableEntity { @OneToOne @JoinColumn(name = "workflowitem_id") - private WorkflowItem workflowItem; + private XmlWorkflowItem workflowItem; // @Column(name = "workflow_id") // @Lob @@ -107,11 +106,11 @@ public class PoolTask implements ReloadableEntity { return workflowId; } - public void setWorkflowItem(WorkflowItem workflowItem) { - this.workflowItem = workflowItem; + public void setWorkflowItem(XmlWorkflowItem xmlWorkflowItem) { + this.workflowItem = xmlWorkflowItem; } - public WorkflowItem getWorkflowItem() { + public XmlWorkflowItem getWorkflowItem() { return this.workflowItem; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTaskServiceImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTaskServiceImpl.java index b3fbdeee60..f64f1b3942 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTaskServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTaskServiceImpl.java @@ -21,7 +21,6 @@ import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; import org.dspace.eperson.service.GroupService; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.PoolTaskDAO; import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; @@ -68,7 +67,7 @@ public class PoolTaskServiceImpl implements PoolTaskService { for (Group group : groups) { List groupTasks = poolTaskDAO.findByGroup(context, group); for (PoolTask poolTask : groupTasks) { - WorkflowItem workflowItem = poolTask.getWorkflowItem(); + XmlWorkflowItem workflowItem = poolTask.getWorkflowItem(); if (inProgressUserService.findByWorkflowItemAndEPerson(context, workflowItem, ePerson) == null) { result.add(poolTask); } @@ -79,12 +78,12 @@ public class PoolTaskServiceImpl implements PoolTaskService { @Override - public List find(Context context, WorkflowItem workflowItem) throws SQLException { + public List find(Context context, XmlWorkflowItem workflowItem) throws SQLException { return poolTaskDAO.findByWorkflowItem(context, workflowItem); } @Override - public PoolTask findByWorkflowIdAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) + public PoolTask findByWorkflowIdAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) throws SQLException, AuthorizeException, IOException { PoolTask poolTask = poolTaskDAO.findByWorkflowItemAndEPerson(context, workflowItem, ePerson); @@ -114,9 +113,9 @@ public class PoolTaskServiceImpl implements PoolTaskService { } @Override - public void deleteByWorkflowItem(Context context, WorkflowItem workflowItem) + public void deleteByWorkflowItem(Context context, XmlWorkflowItem xmlWorkflowItem) throws SQLException, AuthorizeException { - List tasks = find(context, workflowItem); + List tasks = find(context, xmlWorkflowItem); //Use an iterator to remove the tasks ! Iterator iterator = tasks.iterator(); while (iterator.hasNext()) { diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRole.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRole.java index e368709d82..9a7e5a034c 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRole.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRole.java @@ -23,7 +23,6 @@ import org.dspace.core.Context; import org.dspace.core.ReloadableEntity; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; -import org.dspace.workflow.WorkflowItem; /** * Represents a workflow assignments database representation. @@ -52,7 +51,7 @@ public class WorkflowItemRole implements ReloadableEntity { @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "workflowitem_id") - private WorkflowItem workflowItem; + private XmlWorkflowItem workflowItem; @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "eperson_id") @@ -83,11 +82,11 @@ public class WorkflowItemRole implements ReloadableEntity { return this.roleId; } - public void setWorkflowItem(WorkflowItem workflowItem) { - this.workflowItem = workflowItem; + public void setWorkflowItem(XmlWorkflowItem xmlWorkflowItem) { + this.workflowItem = xmlWorkflowItem; } - public WorkflowItem getWorkflowItem() { + public XmlWorkflowItem getWorkflowItem() { return workflowItem; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRoleServiceImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRoleServiceImpl.java index b5872a5271..4204c7dcc3 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRoleServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/WorkflowItemRoleServiceImpl.java @@ -16,7 +16,6 @@ import org.apache.commons.collections4.CollectionUtils; import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.WorkflowItemRoleDAO; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; import org.springframework.beans.factory.annotation.Autowired; @@ -38,20 +37,20 @@ public class WorkflowItemRoleServiceImpl implements WorkflowItemRoleService { } @Override - public List find(Context context, WorkflowItem workflowItem, String role) throws SQLException { + public List find(Context context, XmlWorkflowItem workflowItem, String role) throws SQLException { return workflowItemRoleDAO.findByWorkflowItemAndRole(context, workflowItem, role); } @Override - public List findByWorkflowItem(Context context, WorkflowItem workflowItem) + public List findByWorkflowItem(Context context, XmlWorkflowItem xmlWorkflowItem) throws SQLException { - return workflowItemRoleDAO.findByWorkflowItem(context, workflowItem); + return workflowItemRoleDAO.findByWorkflowItem(context, xmlWorkflowItem); } @Override - public void deleteForWorkflowItem(Context context, WorkflowItem workflowItem) + public void deleteForWorkflowItem(Context context, XmlWorkflowItem xmlWorkflowItem) throws SQLException, AuthorizeException { - Iterator workflowItemRoles = findByWorkflowItem(context, workflowItem).iterator(); + Iterator workflowItemRoles = findByWorkflowItem(context, xmlWorkflowItem).iterator(); while (workflowItemRoles.hasNext()) { WorkflowItemRole workflowItemRole = workflowItemRoles.next(); workflowItemRoles.remove(); diff --git a/dspace-api/src/main/java/org/dspace/workflow/WorkflowItem.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItem.java similarity index 91% rename from dspace-api/src/main/java/org/dspace/workflow/WorkflowItem.java rename to dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItem.java index 9780f15d72..c845578df6 100644 --- a/dspace-api/src/main/java/org/dspace/workflow/WorkflowItem.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItem.java @@ -5,7 +5,7 @@ * * http://www.dspace.org/license/ */ -package org.dspace.workflow; +package org.dspace.xmlworkflow.storedcomponents; import javax.persistence.Column; import javax.persistence.Entity; @@ -24,6 +24,7 @@ import org.dspace.content.InProgressSubmission; import org.dspace.content.Item; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; /** * Class representing an item going through the workflow process in DSpace @@ -35,7 +36,7 @@ import org.dspace.eperson.EPerson; */ @Entity @Table(name = "cwf_workflowitem") -public class WorkflowItem implements InProgressSubmission { +public class XmlWorkflowItem implements InProgressSubmission { @Id @Column(name = "workflowitem_id") @@ -62,9 +63,9 @@ public class WorkflowItem implements InProgressSubmission { /** * Protected constructor, create object using: - * {@link WorkflowItemService#create(Context, Item, Collection)} + * {@link XmlWorkflowItemService#create(Context, Item, Collection)} */ - protected WorkflowItem() { + protected XmlWorkflowItem() { } diff --git a/dspace-api/src/main/java/org/dspace/workflow/WorkflowItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItemServiceImpl.java similarity index 60% rename from dspace-api/src/main/java/org/dspace/workflow/WorkflowItemServiceImpl.java rename to dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItemServiceImpl.java index 7743d7f501..010c310ba6 100644 --- a/dspace-api/src/main/java/org/dspace/workflow/WorkflowItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItemServiceImpl.java @@ -5,7 +5,7 @@ * * http://www.dspace.org/license/ */ -package org.dspace.workflow; +package org.dspace.xmlworkflow.storedcomponents; import java.io.IOException; import java.sql.SQLException; @@ -21,24 +21,24 @@ import org.dspace.core.Context; import org.dspace.core.LogManager; import org.dspace.eperson.EPerson; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; -import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; -import org.dspace.xmlworkflow.storedcomponents.dao.WorkflowItemDAO; +import org.dspace.xmlworkflow.storedcomponents.dao.XmlWorkflowItemDAO; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** - * Service implementation for the WorkflowItem object. - * This class is responsible for all business logic calls for the WorkflowItem object and is autowired by spring. + * Service implementation for the XmlWorkflowItem object. + * This class is responsible for all business logic calls for the XmlWorkflowItem object and is autowired by spring. * This class should never be accessed directly. * * @author kevinvandevelde at atmire.com */ -public class WorkflowItemServiceImpl implements WorkflowItemService { +public class XmlWorkflowItemServiceImpl implements XmlWorkflowItemService { @Autowired(required = true) - protected WorkflowItemDAO workflowItemDAO; + protected XmlWorkflowItemDAO xmlWorkflowItemDAO; @Autowired(required = true) @@ -55,25 +55,25 @@ public class WorkflowItemServiceImpl implements WorkflowItemService { /* * The current step in the workflow system in which this workflow item is present */ - private Logger log = org.apache.logging.log4j.LogManager.getLogger(WorkflowItemServiceImpl.class); + private Logger log = org.apache.logging.log4j.LogManager.getLogger(XmlWorkflowItemServiceImpl.class); - protected WorkflowItemServiceImpl() { + protected XmlWorkflowItemServiceImpl() { } @Override - public WorkflowItem create(Context context, Item item, Collection collection) + public XmlWorkflowItem create(Context context, Item item, Collection collection) throws SQLException, AuthorizeException { - WorkflowItem workflowItem = workflowItemDAO.create(context, new WorkflowItem()); - workflowItem.setItem(item); - workflowItem.setCollection(collection); - return workflowItem; + XmlWorkflowItem xmlWorkflowItem = xmlWorkflowItemDAO.create(context, new XmlWorkflowItem()); + xmlWorkflowItem.setItem(item); + xmlWorkflowItem.setCollection(collection); + return xmlWorkflowItem; } @Override - public WorkflowItem find(Context context, int id) throws SQLException { - WorkflowItem workflowItem = workflowItemDAO.findByID(context, WorkflowItem.class, id); + public XmlWorkflowItem find(Context context, int id) throws SQLException { + XmlWorkflowItem workflowItem = xmlWorkflowItemDAO.findByID(context, XmlWorkflowItem.class, id); if (workflowItem == null) { if (log.isDebugEnabled()) { @@ -90,69 +90,69 @@ public class WorkflowItemServiceImpl implements WorkflowItemService { } @Override - public List findAll(Context context) throws SQLException { - return workflowItemDAO.findAll(context, WorkflowItem.class); + public List findAll(Context context) throws SQLException { + return xmlWorkflowItemDAO.findAll(context, XmlWorkflowItem.class); } @Override - public List findAll(Context context, Integer page, Integer pagesize) throws SQLException { + public List findAll(Context context, Integer page, Integer pagesize) throws SQLException { return findAllInCollection(context, page, pagesize, null); } @Override - public List findAllInCollection(Context context, Integer page, Integer pagesize, - Collection collection) throws SQLException { + public List findAllInCollection(Context context, Integer page, Integer pagesize, + Collection collection) throws SQLException { Integer offset = null; if (page != null && pagesize != null) { offset = page * pagesize; } - return workflowItemDAO.findAllInCollection(context, offset, pagesize, collection); + return xmlWorkflowItemDAO.findAllInCollection(context, offset, pagesize, collection); } @Override public int countAll(Context context) throws SQLException { - return workflowItemDAO.countAll(context); + return xmlWorkflowItemDAO.countAll(context); } @Override public int countAllInCollection(Context context, Collection collection) throws SQLException { - return workflowItemDAO.countAllInCollection(context, collection); + return xmlWorkflowItemDAO.countAllInCollection(context, collection); } @Override - public List findBySubmitter(Context context, EPerson ep) throws SQLException { - return workflowItemDAO.findBySubmitter(context, ep); + public List findBySubmitter(Context context, EPerson ep) throws SQLException { + return xmlWorkflowItemDAO.findBySubmitter(context, ep); } @Override - public List findBySubmitter(Context context, EPerson ep, Integer pageNumber, Integer pageSize) + public List findBySubmitter(Context context, EPerson ep, Integer pageNumber, Integer pageSize) throws SQLException { Integer offset = null; if (pageNumber != null && pageSize != null) { offset = pageNumber * pageSize; } - return workflowItemDAO.findBySubmitter(context, ep, pageNumber, pageSize); + return xmlWorkflowItemDAO.findBySubmitter(context, ep, pageNumber, pageSize); } @Override public int countBySubmitter(Context context, EPerson ep) throws SQLException { - return workflowItemDAO.countBySubmitter(context, ep); + return xmlWorkflowItemDAO.countBySubmitter(context, ep); } @Override public void deleteByCollection(Context context, Collection collection) throws SQLException, IOException, AuthorizeException { - List workflowItems = findByCollection(context, collection); - Iterator iterator = workflowItems.iterator(); + List xmlWorkflowItems = findByCollection(context, collection); + Iterator iterator = xmlWorkflowItems.iterator(); while (iterator.hasNext()) { - WorkflowItem workflowItem = iterator.next(); + XmlWorkflowItem workflowItem = iterator.next(); iterator.remove(); delete(context, workflowItem); } } @Override - public void delete(Context context, WorkflowItem workflowItem) + public void delete(Context context, XmlWorkflowItem workflowItem) throws SQLException, AuthorizeException, IOException { Item item = workflowItem.getItem(); // Need to delete the workspaceitem row first since it refers @@ -164,17 +164,17 @@ public class WorkflowItemServiceImpl implements WorkflowItemService { } @Override - public List findByCollection(Context context, Collection collection) throws SQLException { - return workflowItemDAO.findByCollection(context, collection); + public List findByCollection(Context context, Collection collection) throws SQLException { + return xmlWorkflowItemDAO.findByCollection(context, collection); } @Override - public WorkflowItem findByItem(Context context, Item item) throws SQLException { - return workflowItemDAO.findByItem(context, item); + public XmlWorkflowItem findByItem(Context context, Item item) throws SQLException { + return xmlWorkflowItemDAO.findByItem(context, item); } @Override - public void update(Context context, WorkflowItem workflowItem) throws SQLException, AuthorizeException { + public void update(Context context, XmlWorkflowItem workflowItem) throws SQLException, AuthorizeException { // FIXME check auth log.info(LogManager.getHeader(context, "update_workflow_item", "workflowitem_id=" + workflowItem.getID())); @@ -182,11 +182,11 @@ public class WorkflowItemServiceImpl implements WorkflowItemService { // Update the item itemService.update(context, workflowItem.getItem()); - workflowItemDAO.save(context, workflowItem); + xmlWorkflowItemDAO.save(context, workflowItem); } @Override - public void deleteWrapper(Context context, WorkflowItem workflowItem) throws SQLException, AuthorizeException { + public void deleteWrapper(Context context, XmlWorkflowItem workflowItem) throws SQLException, AuthorizeException { List roles = workflowItemRoleService.findByWorkflowItem(context, workflowItem); Iterator workflowItemRoleIterator = roles.iterator(); while (workflowItemRoleIterator.hasNext()) { @@ -200,12 +200,12 @@ public class WorkflowItemServiceImpl implements WorkflowItemService { claimedTaskService.deleteByWorkflowItem(context, workflowItem); // FIXME - auth? - workflowItemDAO.delete(context, workflowItem); + xmlWorkflowItemDAO.delete(context, workflowItem); } @Override - public void move(Context context, WorkflowItem inProgressSubmission, Collection fromCollection, + public void move(Context context, XmlWorkflowItem inProgressSubmission, Collection fromCollection, Collection toCollection) { // TODO not implemented yet } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/ClaimedTaskDAO.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/ClaimedTaskDAO.java index d7663391fa..7f97e14006 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/ClaimedTaskDAO.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/ClaimedTaskDAO.java @@ -13,8 +13,8 @@ import java.util.List; import org.dspace.core.Context; import org.dspace.core.GenericDAO; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Database Access Object interface class for the ClaimedTask object. @@ -26,21 +26,21 @@ import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; */ public interface ClaimedTaskDAO extends GenericDAO { - public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException; + public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException; - public ClaimedTask findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) + public ClaimedTask findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) throws SQLException; public List findByEperson(Context context, EPerson ePerson) throws SQLException; - public List findByWorkflowItemAndStepId(Context context, WorkflowItem workflowItem, String stepID) + public List findByWorkflowItemAndStepId(Context context, XmlWorkflowItem workflowItem, String stepID) throws SQLException; public ClaimedTask findByEPersonAndWorkflowItemAndStepIdAndActionId(Context context, EPerson ePerson, - WorkflowItem workflowItem, String stepID, + XmlWorkflowItem workflowItem, String stepID, String actionID) throws SQLException; - public List findByWorkflowItemAndStepIdAndActionId(Context c, WorkflowItem workflowItem, + public List findByWorkflowItemAndStepIdAndActionId(Context c, XmlWorkflowItem workflowItem, String stepID, String actionID) throws SQLException; public List findByStep(Context context, String stepID) throws SQLException; diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/InProgressUserDAO.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/InProgressUserDAO.java index ceee789c4b..b08d5afc21 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/InProgressUserDAO.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/InProgressUserDAO.java @@ -13,8 +13,8 @@ import java.util.List; import org.dspace.core.Context; import org.dspace.core.GenericDAO; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.InProgressUser; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Database Access Object interface class for the InProgressUser object. @@ -26,14 +26,14 @@ import org.dspace.xmlworkflow.storedcomponents.InProgressUser; */ public interface InProgressUserDAO extends GenericDAO { - public InProgressUser findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) + public InProgressUser findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) throws SQLException; public List findByEperson(Context context, EPerson ePerson) throws SQLException; - public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException; + public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException; - public int countInProgressUsers(Context context, WorkflowItem workflowItem) throws SQLException; + public int countInProgressUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException; - public int countFinishedUsers(Context context, WorkflowItem workflowItem) throws SQLException; + public int countFinishedUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/PoolTaskDAO.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/PoolTaskDAO.java index ae21f13552..55aed546d9 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/PoolTaskDAO.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/PoolTaskDAO.java @@ -14,8 +14,8 @@ import org.dspace.core.Context; import org.dspace.core.GenericDAO; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.PoolTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Database Access Object interface class for the PoolTask object. @@ -31,11 +31,11 @@ public interface PoolTaskDAO extends GenericDAO { public List findByGroup(Context context, Group group) throws SQLException; - public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException; + public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException; - public PoolTask findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) + public PoolTask findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) throws SQLException; - public PoolTask findByWorkflowItemAndGroup(Context context, Group group, WorkflowItem workflowItem) + public PoolTask findByWorkflowItemAndGroup(Context context, Group group, XmlWorkflowItem workflowItem) throws SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/WorkflowItemRoleDAO.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/WorkflowItemRoleDAO.java index 36acda3473..8ee9e4e4c0 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/WorkflowItemRoleDAO.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/WorkflowItemRoleDAO.java @@ -13,8 +13,8 @@ import java.util.List; import org.dspace.core.Context; import org.dspace.core.GenericDAO; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Database Access Object interface class for the WorkflowItemRole object. @@ -26,10 +26,10 @@ import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; */ public interface WorkflowItemRoleDAO extends GenericDAO { - public List findByWorkflowItemAndRole(Context context, WorkflowItem workflowItem, String role) + public List findByWorkflowItemAndRole(Context context, XmlWorkflowItem workflowItem, String role) throws SQLException; - public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException; + public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException; public List findByEPerson(Context context, EPerson ePerson) throws SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/WorkflowItemDAO.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/XmlWorkflowItemDAO.java similarity index 72% rename from dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/WorkflowItemDAO.java rename to dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/XmlWorkflowItemDAO.java index 2a414fe14a..d0d11886aa 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/WorkflowItemDAO.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/XmlWorkflowItemDAO.java @@ -15,17 +15,17 @@ import org.dspace.content.Item; import org.dspace.core.Context; import org.dspace.core.GenericDAO; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** - * Database Access Object interface class for the WorkflowItem object. - * The implementation of this class is responsible for all database calls for the WorkflowItem object and is + * Database Access Object interface class for the XmlWorkflowItem object. + * The implementation of this class is responsible for all database calls for the XmlWorkflowItem object and is * autowired by spring * This class should only be accessed from a single service and should never be exposed outside of the API * * @author kevinvandevelde at atmire.com */ -public interface WorkflowItemDAO extends GenericDAO { +public interface XmlWorkflowItemDAO extends GenericDAO { /** * Find all the workflow items in a specific collection using the pagination parameters (offset, limit) @@ -41,18 +41,18 @@ public interface WorkflowItemDAO extends GenericDAO { * @return all the workflow items respecting the parameters conditions * @throws SQLException */ - public List findAllInCollection(Context context, Integer offset, Integer limit, - Collection collection) throws SQLException; + public List findAllInCollection(Context context, Integer offset, Integer limit, + Collection collection) throws SQLException; public int countAll(Context context) throws SQLException; public int countAllInCollection(Context context, Collection collection) throws SQLException; - public List findBySubmitter(Context context, EPerson ep) throws SQLException; + public List findBySubmitter(Context context, EPerson ep) throws SQLException; - public List findByCollection(Context context, Collection collection) throws SQLException; + public List findByCollection(Context context, Collection collection) throws SQLException; - public WorkflowItem findByItem(Context context, Item item) throws SQLException; + public XmlWorkflowItem findByItem(Context context, Item item) throws SQLException; /** * Return all the workflow items from a specific submitter respecting the pagination parameters @@ -67,7 +67,7 @@ public interface WorkflowItemDAO extends GenericDAO { * the max number of records to return * @return */ - public List findBySubmitter(Context context, EPerson ep, Integer offset, Integer limit) + public List findBySubmitter(Context context, EPerson ep, Integer offset, Integer limit) throws SQLException; /** diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/ClaimedTaskDAOImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/ClaimedTaskDAOImpl.java index a3063d4756..bb5a167237 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/ClaimedTaskDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/ClaimedTaskDAOImpl.java @@ -16,9 +16,9 @@ import javax.persistence.criteria.Root; import org.dspace.core.AbstractHibernateDAO; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask_; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.ClaimedTaskDAO; /** @@ -34,7 +34,7 @@ public class ClaimedTaskDAOImpl extends AbstractHibernateDAO implem } @Override - public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException { + public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ClaimedTask.class); Root claimedTaskRoot = criteriaQuery.from(ClaimedTask.class); @@ -45,7 +45,7 @@ public class ClaimedTaskDAOImpl extends AbstractHibernateDAO implem } @Override - public ClaimedTask findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) + public ClaimedTask findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ClaimedTask.class); @@ -72,7 +72,7 @@ public class ClaimedTaskDAOImpl extends AbstractHibernateDAO implem } @Override - public List findByWorkflowItemAndStepId(Context context, WorkflowItem workflowItem, String stepID) + public List findByWorkflowItemAndStepId(Context context, XmlWorkflowItem workflowItem, String stepID) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ClaimedTask.class); @@ -88,7 +88,7 @@ public class ClaimedTaskDAOImpl extends AbstractHibernateDAO implem @Override public ClaimedTask findByEPersonAndWorkflowItemAndStepIdAndActionId(Context context, EPerson ePerson, - WorkflowItem workflowItem, String stepID, + XmlWorkflowItem workflowItem, String stepID, String actionID) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, ClaimedTask.class); @@ -105,7 +105,7 @@ public class ClaimedTaskDAOImpl extends AbstractHibernateDAO implem } @Override - public List findByWorkflowItemAndStepIdAndActionId(Context context, WorkflowItem workflowItem, + public List findByWorkflowItemAndStepIdAndActionId(Context context, XmlWorkflowItem workflowItem, String stepID, String actionID) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/InProgressUserDAOImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/InProgressUserDAOImpl.java index 1487864772..cdba1600a8 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/InProgressUserDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/InProgressUserDAOImpl.java @@ -16,9 +16,9 @@ import javax.persistence.criteria.Root; import org.dspace.core.AbstractHibernateDAO; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.InProgressUser; import org.dspace.xmlworkflow.storedcomponents.InProgressUser_; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.InProgressUserDAO; /** @@ -34,7 +34,7 @@ public class InProgressUserDAOImpl extends AbstractHibernateDAO } @Override - public InProgressUser findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) + public InProgressUser findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); @@ -61,7 +61,7 @@ public class InProgressUserDAOImpl extends AbstractHibernateDAO } @Override - public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException { + public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, InProgressUser.class); @@ -72,7 +72,7 @@ public class InProgressUserDAOImpl extends AbstractHibernateDAO } @Override - public int countInProgressUsers(Context context, WorkflowItem workflowItem) throws SQLException { + public int countInProgressUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Long.class); @@ -88,7 +88,7 @@ public class InProgressUserDAOImpl extends AbstractHibernateDAO } @Override - public int countFinishedUsers(Context context, WorkflowItem workflowItem) throws SQLException { + public int countFinishedUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Long.class); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/PoolTaskDAOImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/PoolTaskDAOImpl.java index 2d4bfceb81..b38041da39 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/PoolTaskDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/PoolTaskDAOImpl.java @@ -17,9 +17,9 @@ import org.dspace.core.AbstractHibernateDAO; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.PoolTask; import org.dspace.xmlworkflow.storedcomponents.PoolTask_; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.PoolTaskDAO; /** @@ -56,7 +56,7 @@ public class PoolTaskDAOImpl extends AbstractHibernateDAO implements P } @Override - public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException { + public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, PoolTask.class); Root poolTaskRoot = criteriaQuery.from(PoolTask.class); @@ -66,7 +66,7 @@ public class PoolTaskDAOImpl extends AbstractHibernateDAO implements P } @Override - public PoolTask findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) + public PoolTask findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, PoolTask.class); @@ -81,7 +81,7 @@ public class PoolTaskDAOImpl extends AbstractHibernateDAO implements P } @Override - public PoolTask findByWorkflowItemAndGroup(Context context, Group group, WorkflowItem workflowItem) + public PoolTask findByWorkflowItemAndGroup(Context context, Group group, XmlWorkflowItem workflowItem) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, PoolTask.class); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemDAOImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemDAOImpl.java deleted file mode 100644 index 53827a95f0..0000000000 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemDAOImpl.java +++ /dev/null @@ -1,137 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.xmlworkflow.storedcomponents.dao.impl; - -import java.sql.SQLException; -import java.util.List; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Join; -import javax.persistence.criteria.Root; - -import org.dspace.content.Collection; -import org.dspace.content.Item; -import org.dspace.content.Item_; -import org.dspace.core.AbstractHibernateDAO; -import org.dspace.core.Context; -import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowItem_; -import org.dspace.xmlworkflow.storedcomponents.dao.WorkflowItemDAO; - -/** - * Hibernate implementation of the Database Access Object interface class for the WorkflowItem object. - * This class is responsible for all database calls for the WorkflowItem object and is autowired by spring - * This class should never be accessed directly. - * - * @author kevinvandevelde at atmire.com - */ -public class WorkflowItemDAOImpl extends AbstractHibernateDAO implements WorkflowItemDAO { - - protected WorkflowItemDAOImpl() { - super(); - } - - @Override - public List findAllInCollection(Context context, Integer offset, - Integer limit, - Collection collection) throws SQLException { - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, WorkflowItem.class); - Root workflowItemRoot = criteriaQuery.from(WorkflowItem.class); - criteriaQuery.select(workflowItemRoot); - if (collection != null) { - criteriaQuery.where(criteriaBuilder.equal(workflowItemRoot.get(WorkflowItem_.collection), - collection)); - } - if (offset == null) { - offset = -1; - } - if (limit == null) { - limit = -1; - } - criteriaQuery.orderBy(criteriaBuilder.asc(workflowItemRoot.get(WorkflowItem_.id))); - return list(context, criteriaQuery, false, WorkflowItem.class, limit, offset); - } - - @Override - public int countAll(Context context) throws SQLException { - return countAllInCollection(context, null); - } - - @Override - public int countAllInCollection(Context context, Collection collection) throws SQLException { - - - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Long.class); - - Root workflowItemRoot = criteriaQuery.from(WorkflowItem.class); - if (collection != null) { - criteriaQuery.where(criteriaBuilder.equal(workflowItemRoot.get(WorkflowItem_.collection), - collection)); - } - return count(context, criteriaQuery, criteriaBuilder, workflowItemRoot); - } - - @Override - public List findBySubmitter(Context context, EPerson ep) throws SQLException { - return findBySubmitter(context, ep, null, null); - } - - @Override - public List findBySubmitter(Context context, EPerson ep, Integer offset, Integer limit) - throws SQLException { - if (offset == null) { - offset = -1; - } - if (limit == null) { - limit = -1; - } - - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, WorkflowItem.class); - Root workflowItemRoot = criteriaQuery.from(WorkflowItem.class); - Join join = workflowItemRoot.join("item"); - criteriaQuery.select(workflowItemRoot); - criteriaQuery.where(criteriaBuilder.equal(join.get(Item_.submitter), ep)); - criteriaQuery.orderBy(criteriaBuilder.asc(workflowItemRoot.get(WorkflowItem_.id))); - return list(context, criteriaQuery, false, WorkflowItem.class, limit, offset); - } - - @Override - public int countBySubmitter(Context context, EPerson ep) throws SQLException { - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Long.class); - Root workflowItemRoot = criteriaQuery.from(WorkflowItem.class); - Join join = workflowItemRoot.join("item"); - criteriaQuery.where(criteriaBuilder.equal(join.get(Item_.submitter), ep)); - return count(context, criteriaQuery, criteriaBuilder, workflowItemRoot); - } - - @Override - public List findByCollection(Context context, Collection collection) throws SQLException { - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, WorkflowItem.class); - Root workflowItemRoot = criteriaQuery.from(WorkflowItem.class); - criteriaQuery.select(workflowItemRoot); - criteriaQuery.where(criteriaBuilder.equal(workflowItemRoot.get(WorkflowItem_.collection), collection)); - criteriaQuery.orderBy(criteriaBuilder.asc(workflowItemRoot.get(WorkflowItem_.id))); - return list(context, criteriaQuery, false, WorkflowItem.class, -1, -1); - } - - @Override - public WorkflowItem findByItem(Context context, Item item) throws SQLException { - CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); - CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, WorkflowItem.class); - Root workflowItemRoot = criteriaQuery.from(WorkflowItem.class); - criteriaQuery.select(workflowItemRoot); - criteriaQuery.where(criteriaBuilder.equal(workflowItemRoot.get(WorkflowItem_.item), item)); - return uniqueResult(context, criteriaQuery, false, WorkflowItem.class, -1, -1); - } -} diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemRoleDAOImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemRoleDAOImpl.java index ca7b2c78ad..fdc2413b5f 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemRoleDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/WorkflowItemRoleDAOImpl.java @@ -16,9 +16,9 @@ import javax.persistence.criteria.Root; import org.dspace.core.AbstractHibernateDAO; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole_; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.dao.WorkflowItemRoleDAO; /** @@ -36,7 +36,7 @@ public class WorkflowItemRoleDAOImpl extends AbstractHibernateDAO findByWorkflowItemAndRole(Context context, - WorkflowItem workflowItem, + XmlWorkflowItem workflowItem, String role) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, WorkflowItemRole.class); @@ -55,7 +55,7 @@ public class WorkflowItemRoleDAOImpl extends AbstractHibernateDAO findByWorkflowItem(Context context, - WorkflowItem workflowItem) throws SQLException { + XmlWorkflowItem workflowItem) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, WorkflowItemRole.class); Root workflowItemRoleRoot = criteriaQuery.from(WorkflowItemRole.class); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/XmlWorkflowItemDAOImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/XmlWorkflowItemDAOImpl.java new file mode 100644 index 0000000000..51728af7a4 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/dao/impl/XmlWorkflowItemDAOImpl.java @@ -0,0 +1,137 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.xmlworkflow.storedcomponents.dao.impl; + +import java.sql.SQLException; +import java.util.List; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Join; +import javax.persistence.criteria.Root; + +import org.dspace.content.Collection; +import org.dspace.content.Item; +import org.dspace.content.Item_; +import org.dspace.core.AbstractHibernateDAO; +import org.dspace.core.Context; +import org.dspace.eperson.EPerson; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem_; +import org.dspace.xmlworkflow.storedcomponents.dao.XmlWorkflowItemDAO; + +/** + * Hibernate implementation of the Database Access Object interface class for the XmlWorkflowItem object. + * This class is responsible for all database calls for the XmlWorkflowItem object and is autowired by spring + * This class should never be accessed directly. + * + * @author kevinvandevelde at atmire.com + */ +public class XmlWorkflowItemDAOImpl extends AbstractHibernateDAO implements XmlWorkflowItemDAO { + + protected XmlWorkflowItemDAOImpl() { + super(); + } + + @Override + public List findAllInCollection(Context context, Integer offset, + Integer limit, + Collection collection) throws SQLException { + CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); + CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, XmlWorkflowItem.class); + Root xmlWorkflowItemRoot = criteriaQuery.from(XmlWorkflowItem.class); + criteriaQuery.select(xmlWorkflowItemRoot); + if (collection != null) { + criteriaQuery.where(criteriaBuilder.equal(xmlWorkflowItemRoot.get(XmlWorkflowItem_.collection), + collection)); + } + if (offset == null) { + offset = -1; + } + if (limit == null) { + limit = -1; + } + criteriaQuery.orderBy(criteriaBuilder.asc(xmlWorkflowItemRoot.get(XmlWorkflowItem_.id))); + return list(context, criteriaQuery, false, XmlWorkflowItem.class, limit, offset); + } + + @Override + public int countAll(Context context) throws SQLException { + return countAllInCollection(context, null); + } + + @Override + public int countAllInCollection(Context context, Collection collection) throws SQLException { + + + CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); + CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Long.class); + + Root xmlWorkflowItemRoot = criteriaQuery.from(XmlWorkflowItem.class); + if (collection != null) { + criteriaQuery.where(criteriaBuilder.equal(xmlWorkflowItemRoot.get(XmlWorkflowItem_.collection), + collection)); + } + return count(context, criteriaQuery, criteriaBuilder, xmlWorkflowItemRoot); + } + + @Override + public List findBySubmitter(Context context, EPerson ep) throws SQLException { + return findBySubmitter(context, ep, null, null); + } + + @Override + public List findBySubmitter(Context context, EPerson ep, Integer offset, Integer limit) + throws SQLException { + if (offset == null) { + offset = -1; + } + if (limit == null) { + limit = -1; + } + + CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); + CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, XmlWorkflowItem.class); + Root xmlWorkflowItemRoot = criteriaQuery.from(XmlWorkflowItem.class); + Join join = xmlWorkflowItemRoot.join("item"); + criteriaQuery.select(xmlWorkflowItemRoot); + criteriaQuery.where(criteriaBuilder.equal(join.get(Item_.submitter), ep)); + criteriaQuery.orderBy(criteriaBuilder.asc(xmlWorkflowItemRoot.get(XmlWorkflowItem_.id))); + return list(context, criteriaQuery, false, XmlWorkflowItem.class, limit, offset); + } + + @Override + public int countBySubmitter(Context context, EPerson ep) throws SQLException { + CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); + CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Long.class); + Root xmlWorkflowItemRoot = criteriaQuery.from(XmlWorkflowItem.class); + Join join = xmlWorkflowItemRoot.join("item"); + criteriaQuery.where(criteriaBuilder.equal(join.get(Item_.submitter), ep)); + return count(context, criteriaQuery, criteriaBuilder, xmlWorkflowItemRoot); + } + + @Override + public List findByCollection(Context context, Collection collection) throws SQLException { + CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); + CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, XmlWorkflowItem.class); + Root xmlWorkflowItemRoot = criteriaQuery.from(XmlWorkflowItem.class); + criteriaQuery.select(xmlWorkflowItemRoot); + criteriaQuery.where(criteriaBuilder.equal(xmlWorkflowItemRoot.get(XmlWorkflowItem_.collection), collection)); + criteriaQuery.orderBy(criteriaBuilder.asc(xmlWorkflowItemRoot.get(XmlWorkflowItem_.id))); + return list(context, criteriaQuery, false, XmlWorkflowItem.class, -1, -1); + } + + @Override + public XmlWorkflowItem findByItem(Context context, Item item) throws SQLException { + CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); + CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, XmlWorkflowItem.class); + Root xmlWorkflowItemRoot = criteriaQuery.from(XmlWorkflowItem.class); + criteriaQuery.select(xmlWorkflowItemRoot); + criteriaQuery.where(criteriaBuilder.equal(xmlWorkflowItemRoot.get(XmlWorkflowItem_.item), item)); + return uniqueResult(context, criteriaQuery, false, XmlWorkflowItem.class, -1, -1); + } +} diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/ClaimedTaskService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/ClaimedTaskService.java index 052d28d037..667ca898b5 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/ClaimedTaskService.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/ClaimedTaskService.java @@ -14,8 +14,8 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.service.DSpaceCRUDService; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Service interface class for the ClaimedTask object. @@ -26,26 +26,26 @@ import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; */ public interface ClaimedTaskService extends DSpaceCRUDService { - public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException; + public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException; - public ClaimedTask findByWorkflowIdAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) + public ClaimedTask findByWorkflowIdAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) throws SQLException; public List findByEperson(Context context, EPerson ePerson) throws SQLException; - public List find(Context context, WorkflowItem workflowItem, String stepID) throws SQLException; + public List find(Context context, XmlWorkflowItem workflowItem, String stepID) throws SQLException; - public ClaimedTask find(Context context, EPerson ePerson, WorkflowItem workflowItem, String stepID, + public ClaimedTask find(Context context, EPerson ePerson, XmlWorkflowItem workflowItem, String stepID, String actionID) throws SQLException; - public List find(Context context, WorkflowItem workflowItem, String stepID, String actionID) + public List find(Context context, XmlWorkflowItem workflowItem, String stepID, String actionID) throws SQLException; - public List find(Context context, WorkflowItem workflowItem) throws SQLException; + public List find(Context context, XmlWorkflowItem workflowItem) throws SQLException; public List findAllInStep(Context context, String stepID) throws SQLException; - public void deleteByWorkflowItem(Context context, WorkflowItem workflowItem) + public void deleteByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException, AuthorizeException; List findAll(Context context) throws SQLException; diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/InProgressUserService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/InProgressUserService.java index fa2631bbf0..d90d73e7c9 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/InProgressUserService.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/InProgressUserService.java @@ -13,8 +13,8 @@ import java.util.List; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.service.DSpaceCRUDService; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.InProgressUser; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Service interface class for the InProgressUser object. @@ -24,14 +24,14 @@ import org.dspace.xmlworkflow.storedcomponents.InProgressUser; * @author kevinvandevelde at atmire.com */ public interface InProgressUserService extends DSpaceCRUDService { - public InProgressUser findByWorkflowItemAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) + public InProgressUser findByWorkflowItemAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) throws SQLException; public List findByEperson(Context context, EPerson ePerson) throws SQLException; - public List findByWorkflowItem(Context context, WorkflowItem workflowItem) throws SQLException; + public List findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException; - public int getNumberOfInProgressUsers(Context context, WorkflowItem workflowItem) throws SQLException; + public int getNumberOfInProgressUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException; - public int getNumberOfFinishedUsers(Context context, WorkflowItem workflowItem) throws SQLException; + public int getNumberOfFinishedUsers(Context context, XmlWorkflowItem workflowItem) throws SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/PoolTaskService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/PoolTaskService.java index 08e0a342b4..7f5ed5e6a0 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/PoolTaskService.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/PoolTaskService.java @@ -16,8 +16,8 @@ import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; import org.dspace.service.DSpaceCRUDService; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.PoolTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Service interface class for the PoolTask object. @@ -33,12 +33,12 @@ public interface PoolTaskService extends DSpaceCRUDService { public List findByEperson(Context context, EPerson ePerson) throws SQLException, AuthorizeException, IOException; - public List find(Context context, WorkflowItem workflowItem) throws SQLException; + public List find(Context context, XmlWorkflowItem workflowItem) throws SQLException; - public PoolTask findByWorkflowIdAndEPerson(Context context, WorkflowItem workflowItem, EPerson ePerson) + public PoolTask findByWorkflowIdAndEPerson(Context context, XmlWorkflowItem workflowItem, EPerson ePerson) throws SQLException, AuthorizeException, IOException; - public void deleteByWorkflowItem(Context context, WorkflowItem workflowItem) + public void deleteByWorkflowItem(Context context, XmlWorkflowItem xmlWorkflowItem) throws SQLException, AuthorizeException; public void deleteByEperson(Context context, EPerson ePerson) throws SQLException, AuthorizeException, IOException; diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/WorkflowItemRoleService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/WorkflowItemRoleService.java index 33b2f6a007..9f909231f1 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/WorkflowItemRoleService.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/WorkflowItemRoleService.java @@ -14,8 +14,8 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.service.DSpaceCRUDService; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * Service interface class for the WorkflowItemRole object. @@ -26,12 +26,12 @@ import org.dspace.xmlworkflow.storedcomponents.WorkflowItemRole; */ public interface WorkflowItemRoleService extends DSpaceCRUDService { - public List find(Context context, WorkflowItem workflowItem, String role) throws SQLException; + public List find(Context context, XmlWorkflowItem workflowItem, String role) throws SQLException; - public List findByWorkflowItem(Context context, WorkflowItem workflowItem) + public List findByWorkflowItem(Context context, XmlWorkflowItem xmlWorkflowItem) throws SQLException; - public void deleteForWorkflowItem(Context context, WorkflowItem wfi) throws SQLException, AuthorizeException; + public void deleteForWorkflowItem(Context context, XmlWorkflowItem wfi) throws SQLException, AuthorizeException; public void deleteByEPerson(Context context, EPerson ePerson) throws SQLException, AuthorizeException; diff --git a/dspace-api/src/main/java/org/dspace/workflow/WorkflowItemService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/XmlWorkflowItemService.java similarity index 82% rename from dspace-api/src/main/java/org/dspace/workflow/WorkflowItemService.java rename to dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/XmlWorkflowItemService.java index 5327b55515..ebb9614a72 100644 --- a/dspace-api/src/main/java/org/dspace/workflow/WorkflowItemService.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/XmlWorkflowItemService.java @@ -5,7 +5,7 @@ * * http://www.dspace.org/license/ */ -package org.dspace.workflow; +package org.dspace.xmlworkflow.storedcomponents.service; import java.io.IOException; import java.sql.SQLException; @@ -17,18 +17,18 @@ import org.dspace.content.Item; import org.dspace.content.service.InProgressSubmissionService; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** - * Service interface class for the Workflow items. - * All WorkflowItem service classes should implement this class since it offers some basic methods which all - * WorkflowItems - * are required to have. + * Service interface class for the XmlWorkflowItem object. + * The implementation of this class is responsible for all business logic calls for the XmlWorkflowItem object and is + * autowired by spring * * @author kevinvandevelde at atmire.com */ -public interface WorkflowItemService extends InProgressSubmissionService { +public interface XmlWorkflowItemService extends InProgressSubmissionService { - public WorkflowItem create(Context context, Item item, Collection collection) throws SQLException, + public XmlWorkflowItem create(Context context, Item item, Collection collection) throws SQLException, AuthorizeException; /** @@ -39,7 +39,7 @@ public interface WorkflowItemService extends InProgressSubmissionService findAll(Context context) throws SQLException; + public List findAll(Context context) throws SQLException; /** * Get all workflow items for a particular collection. @@ -58,7 +58,7 @@ public interface WorkflowItemService extends InProgressSubmissionService findByCollection(Context context, Collection collection) throws SQLException; + public List findByCollection(Context context, Collection collection) throws SQLException; /** * Check to see if a particular item is currently under Workflow. @@ -69,7 +69,7 @@ public interface WorkflowItemService extends InProgressSubmissionService findBySubmitter(Context context, EPerson ep) throws SQLException; + public List findBySubmitter(Context context, EPerson ep) throws SQLException; /** * Delete all workflow items present in the specified collection. @@ -105,7 +105,7 @@ public interface WorkflowItemService extends InProgressSubmissionService findAll(Context context, Integer page, Integer pagesize) throws SQLException; + public List findAll(Context context, Integer page, Integer pagesize) throws SQLException; /** * return all workflowitems for a certain page with a certain collection @@ -129,7 +129,7 @@ public interface WorkflowItemService extends InProgressSubmissionService findAllInCollection(Context context, Integer page, Integer pagesize, + public List findAllInCollection(Context context, Integer page, Integer pagesize, Collection collection) throws SQLException; /** @@ -165,7 +165,7 @@ public interface WorkflowItemService extends InProgressSubmissionService findBySubmitter(Context context, EPerson ep, Integer pageNumber, Integer pageSize) + public List findBySubmitter(Context context, EPerson ep, Integer pageNumber, Integer pageSize) throws SQLException; /** diff --git a/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java b/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java index ab6da04605..31c0298824 100644 --- a/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java @@ -44,13 +44,13 @@ import org.dspace.scripts.service.ProcessService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.versioning.factory.VersionServiceFactory; import org.dspace.versioning.service.VersionHistoryService; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflow.WorkflowService; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.InProgressUserService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.dspace.xmlworkflow.storedcomponents.service.WorkflowItemRoleService; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; /** * Abstract builder class that holds references to all available services @@ -66,8 +66,8 @@ public abstract class AbstractBuilder { static ItemService itemService; static InstallItemService installItemService; static WorkspaceItemService workspaceItemService; - static WorkflowItemService workflowItemService; - static WorkflowService workflowService; + static XmlWorkflowItemService workflowItemService; + static XmlWorkflowService workflowService; static EPersonService ePersonService; static GroupService groupService; static BundleService bundleService; @@ -115,8 +115,8 @@ public abstract class AbstractBuilder { itemService = ContentServiceFactory.getInstance().getItemService(); installItemService = ContentServiceFactory.getInstance().getInstallItemService(); workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); - workflowItemService = WorkflowServiceFactory.getInstance().getWorkflowItemService(); - workflowService = WorkflowServiceFactory.getInstance().getWorkflowService(); + workflowItemService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService(); + workflowService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); groupService = EPersonServiceFactory.getInstance().getGroupService(); bundleService = ContentServiceFactory.getInstance().getBundleService(); @@ -138,10 +138,10 @@ public abstract class AbstractBuilder { processService = ScriptServiceFactory.getInstance().getProcessService(); // Temporarily disabled - claimedTaskService = WorkflowServiceFactory.getInstance().getClaimedTaskService(); - inProgressUserService = WorkflowServiceFactory.getInstance().getInProgressUserService(); - poolTaskService = WorkflowServiceFactory.getInstance().getPoolTaskService(); - workflowItemRoleService = WorkflowServiceFactory.getInstance().getWorkflowItemRoleService(); + claimedTaskService = XmlWorkflowServiceFactory.getInstance().getClaimedTaskService(); + inProgressUserService = XmlWorkflowServiceFactory.getInstance().getInProgressUserService(); + poolTaskService = XmlWorkflowServiceFactory.getInstance().getPoolTaskService(); + workflowItemRoleService = XmlWorkflowServiceFactory.getInstance().getWorkflowItemRoleService(); } diff --git a/dspace-api/src/test/java/org/dspace/builder/ClaimedTaskBuilder.java b/dspace-api/src/test/java/org/dspace/builder/ClaimedTaskBuilder.java index fa66d78b8a..343b1d281c 100644 --- a/dspace-api/src/test/java/org/dspace/builder/ClaimedTaskBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/ClaimedTaskBuilder.java @@ -20,13 +20,13 @@ import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.event.Event; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.PoolTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; /** @@ -37,7 +37,7 @@ public class ClaimedTaskBuilder extends AbstractBuilder private WorkspaceItem workspaceItem; - private WorkflowItem workflowItem; + private XmlWorkflowItem workflowItem; private PoolTask poolTask; diff --git a/dspace-api/src/test/java/org/dspace/builder/WorkflowItemBuilder.java b/dspace-api/src/test/java/org/dspace/builder/WorkflowItemBuilder.java index cf772ffd7c..bd76e9e613 100644 --- a/dspace-api/src/test/java/org/dspace/builder/WorkflowItemBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/WorkflowItemBuilder.java @@ -22,21 +22,21 @@ import org.dspace.content.WorkspaceItem; import org.dspace.core.Context; import org.dspace.discovery.SearchServiceException; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowItemService; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; /** * Builder to construct WorkflowItem objects * **/ -public class WorkflowItemBuilder extends AbstractBuilder { +public class WorkflowItemBuilder extends AbstractBuilder { /** Keep a reference to the underlying Item for cleanup **/ private Item item; private WorkspaceItem workspaceItem; - private WorkflowItem workflowItem; + private XmlWorkflowItem workflowItem; protected WorkflowItemBuilder(Context context) { super(context); @@ -72,7 +72,7 @@ public class WorkflowItemBuilder extends AbstractBuilder { + extends AInprogressItemConverter { public WorkflowItemConverter() throws SubmissionConfigReaderException { super(); } @Override - public WorkflowItemRest convert(WorkflowItem obj, Projection projection) { + public WorkflowItemRest convert(XmlWorkflowItem obj, Projection projection) { WorkflowItemRest witem = new WorkflowItemRest(); witem.setProjection(projection); fillFromModel(obj, witem, projection); @@ -38,12 +38,12 @@ public class WorkflowItemConverter } @Override - public Class getModelClass() { - return WorkflowItem.class; + public Class getModelClass() { + return XmlWorkflowItem.class; } @Override public boolean supportsModel(IndexableObject object) { - return object.getIndexedObject() instanceof WorkflowItem; + return object.getIndexedObject() instanceof XmlWorkflowItem; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java index ce63b1760b..bc71290c1c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java @@ -33,16 +33,16 @@ import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.service.EPersonService; import org.dspace.workflow.WorkflowException; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowService; -import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.WorkflowConfigurationException; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; +import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.state.actions.Action; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; @@ -75,7 +75,7 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { try { long total = wis.countAll(context); - List witems = wis.findAll(context, pageable.getPageNumber(), pageable.getPageSize()); + List witems = wis.findAll(context, pageable.getPageNumber(), pageable.getPageSize()); return converter.toRestPage(witems, pageable, total, utils.obtainProjection()); } catch (SQLException e) { throw new RuntimeException("SQLException in " + this.getClass() + "#findAll trying to retrieve all " + @@ -154,7 +154,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository witems = wis.findBySubmitter(context, ep, pageable.getPageNumber(), + List witems = wis.findBySubmitter(context, ep, pageable.getPageNumber(), pageable.getPageSize()); return converter.toRestPage(witems, pageable, total, utils.obtainProjection()); } catch (SQLException e) { @@ -165,7 +165,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository stringList) { - WorkflowItem source; + XmlWorkflowItem source; if (stringList == null || stringList.isEmpty() || stringList.size() > 1) { throw new UnprocessableEntityException("The given URI list could not be properly parsed to one result"); } @@ -198,7 +198,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository operations = patch.getOperations(); WorkflowItemRest wsi = findOne(context, id); - WorkflowItem source = wis.find(context, id); + XmlWorkflowItem source = wis.find(context, id); this.checkIfEditMetadataAllowedInCurrentStep(context, source); @@ -267,7 +267,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository poolTasks = poolTaskService.find(context, workflowItem); - List claimedTasks = claimedTaskService.find(context, workflowItem); + List poolTasks = poolTaskService.find(context, xmlWorkflowItem); + List claimedTasks = claimedTaskService.find(context, xmlWorkflowItem); for (PoolTask poolTask : poolTasks) { return converter.toRest(xmlWorkflowFactory.getStepByName(poolTask.getStepID()), projection); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/PoolTaskRestPermissionEvaluatorPlugin.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/PoolTaskRestPermissionEvaluatorPlugin.java index 4e325cfc00..d369cffcf9 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/PoolTaskRestPermissionEvaluatorPlugin.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/PoolTaskRestPermissionEvaluatorPlugin.java @@ -20,8 +20,8 @@ import org.dspace.eperson.EPerson; import org.dspace.eperson.service.EPersonService; import org.dspace.services.RequestService; import org.dspace.services.model.Request; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.PoolTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -72,7 +72,7 @@ public class PoolTaskRestPermissionEvaluatorPlugin extends RestObjectPermissionE return true; } - WorkflowItem workflowItem = poolTask.getWorkflowItem(); + XmlWorkflowItem workflowItem = poolTask.getWorkflowItem(); PoolTask poolTask2 = poolTaskService.findByWorkflowIdAndEPerson(context, workflowItem, ePerson); if (poolTask2 != null && poolTask2.getID().equals(poolTask.getID())) { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/WorkflowRestPermissionEvaluatorPlugin.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/WorkflowRestPermissionEvaluatorPlugin.java index 75f8647135..a4c452d9c3 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/WorkflowRestPermissionEvaluatorPlugin.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/WorkflowRestPermissionEvaluatorPlugin.java @@ -20,10 +20,10 @@ import org.dspace.eperson.EPerson; import org.dspace.eperson.service.EPersonService; import org.dspace.services.RequestService; import org.dspace.services.model.Request; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowItemService; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -45,7 +45,7 @@ public class WorkflowRestPermissionEvaluatorPlugin extends RestObjectPermissionE private RequestService requestService; @Autowired - private WorkflowItemService workflowItemService; + private XmlWorkflowItemService workflowItemService; @Autowired private PoolTaskService poolTaskService; @@ -76,7 +76,7 @@ public class WorkflowRestPermissionEvaluatorPlugin extends RestObjectPermissionE return false; } Integer dsoId = Integer.parseInt(targetId.toString()); - WorkflowItem workflowItem = workflowItemService.find(context, dsoId); + XmlWorkflowItem workflowItem = workflowItemService.find(context, dsoId); // submitter can see their inprogress submission if (ePerson.equals(workflowItem.getSubmitter())) { return true; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/SubmissionService.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/SubmissionService.java index b80852e6f3..7da5a3b71a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/SubmissionService.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/SubmissionService.java @@ -49,9 +49,9 @@ import org.dspace.services.ConfigurationService; import org.dspace.services.RequestService; import org.dspace.services.model.Request; import org.dspace.workflow.WorkflowException; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflow.WorkflowService; +import org.dspace.xmlworkflow.service.XmlWorkflowService; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.datasource.init.UncategorizedScriptException; import org.springframework.stereotype.Component; @@ -75,9 +75,9 @@ public class SubmissionService { @Autowired protected WorkspaceItemService workspaceItemService; @Autowired - protected WorkflowItemService workflowItemService; + protected XmlWorkflowItemService workflowItemService; @Autowired - protected WorkflowService workflowService; + protected XmlWorkflowService workflowService; @Autowired protected CreativeCommonsService creativeCommonsService; @Autowired @@ -215,9 +215,9 @@ public class SubmissionService { * @throws AuthorizeException * @throws WorkflowException */ - public WorkflowItem createWorkflowItem(Context context, String requestUriListString) + public XmlWorkflowItem createWorkflowItem(Context context, String requestUriListString) throws SQLException, AuthorizeException, WorkflowException { - WorkflowItem wi = null; + XmlWorkflowItem wi = null; if (StringUtils.isBlank(requestUriListString)) { throw new UnprocessableEntityException("Malformed body..." + requestUriListString); } @@ -271,7 +271,7 @@ public class SubmissionService { return accessCondition; } - public void saveWorkflowItem(Context context, WorkflowItem source) throws SQLException, AuthorizeException { + public void saveWorkflowItem(Context context, XmlWorkflowItem source) throws SQLException, AuthorizeException { workflowItemService.update(context, source); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionGroupRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionGroupRestControllerIT.java index 767ea5f565..19fe98a3a6 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionGroupRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionGroupRestControllerIT.java @@ -33,7 +33,7 @@ import org.dspace.content.service.CollectionService; import org.dspace.core.Constants; import org.dspace.eperson.Group; import org.dspace.eperson.service.GroupService; -import org.dspace.workflow.WorkflowService; +import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -51,7 +51,7 @@ public class CollectionGroupRestControllerIT extends AbstractControllerIntegrati private AuthorizeService authorizeService; @Autowired - private WorkflowService workflowService; + private XmlWorkflowService workflowService; Collection collection; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java index 7478d67a35..8b9c633678 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java @@ -52,8 +52,8 @@ import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.hamcrest.Matchers; import org.junit.Ignore; import org.junit.Test; @@ -3648,7 +3648,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest WorkspaceItem wsItem2 = WorkspaceItemBuilder.createWorkspaceItem(context, col2).withTitle("Workspace Item 2") .build(); - WorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") + XmlWorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") .build(); // 4. a claimed task from the administrator @@ -3663,7 +3663,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest WorkspaceItem wsItem2Admin = WorkspaceItemBuilder.createWorkspaceItem(context, col2) .withTitle("Admin Workspace Item 2").build(); - WorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Admin Workflow Item 1").build(); context.restoreAuthSystemState(); @@ -3784,7 +3784,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .withIssueDate("2010-11-03") .build(); - WorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") + XmlWorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") .withIssueDate("2010-11-03") .build(); @@ -3803,7 +3803,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .withIssueDate("2010-11-03") .withTitle("Admin Workspace Item 2").build(); - WorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) .withIssueDate("2010-11-03") .withTitle("Admin Workflow Item 1").build(); @@ -3987,7 +3987,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .withIssueDate("2010-11-03") .build(); - WorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") + XmlWorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") .withIssueDate("2010-11-03") .build(); @@ -4006,7 +4006,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .withIssueDate("2010-11-03") .withTitle("Admin Workspace Item 2").build(); - WorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) .withIssueDate("2010-11-03") .withTitle("Admin Workflow Item 1").build(); @@ -4257,7 +4257,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .withIssueDate("2010-11-03") .build(); - WorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") + XmlWorkflowItem wfItem1 = WorkflowItemBuilder.createWorkflowItem(context, col2).withTitle("Workflow Item 1") .withIssueDate("2010-11-03") .build(); @@ -4276,7 +4276,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .withIssueDate("2010-11-03") .withTitle("Admin Workspace Item 2").build(); - WorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem wfItem1Admin = WorkflowItemBuilder.createWorkflowItem(context, col2) .withIssueDate("2010-11-03") .withTitle("Admin Workflow Item 1").build(); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java index 084c08b231..1f09fe80d0 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java @@ -75,7 +75,7 @@ import org.dspace.eperson.service.AccountService; import org.dspace.eperson.service.EPersonService; import org.dspace.eperson.service.RegistrationDataService; import org.dspace.services.ConfigurationService; -import org.dspace.workflow.WorkflowService; +import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.hamcrest.Matchers; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -93,7 +93,7 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest { private EPersonService ePersonService; @Autowired - private WorkflowService workflowService; + private XmlWorkflowService workflowService; @Autowired private RegistrationDataDAO registrationDataDAO; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/LoginAsEPersonIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/LoginAsEPersonIT.java index f9c58055ef..95412b514d 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/LoginAsEPersonIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/LoginAsEPersonIT.java @@ -40,8 +40,8 @@ import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; import org.dspace.eperson.service.GroupService; import org.dspace.services.ConfigurationService; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.PoolTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; @@ -250,7 +250,7 @@ public class LoginAsEPersonIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem = poolTask.getWorkflowItem(); + XmlWorkflowItem witem = poolTask.getWorkflowItem(); context.restoreAuthSystemState(); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java index b699eef709..a7813601ec 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java @@ -45,12 +45,12 @@ import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.Item; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.PoolTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.hamcrest.Matchers; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -290,21 +290,21 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //5. our workflow items - WorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 2") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 3") .withIssueDate("2017-10-18") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -434,21 +434,21 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //5. our workflow items - WorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 2") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 3") .withIssueDate("2017-10-18") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -566,7 +566,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem = poolTask.getWorkflowItem(); + XmlWorkflowItem witem = poolTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -640,7 +640,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem = poolTask.getWorkflowItem(); + XmlWorkflowItem witem = poolTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -703,7 +703,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem = poolTask.getWorkflowItem(); + XmlWorkflowItem witem = poolTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -768,7 +768,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -833,7 +833,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -892,7 +892,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -948,7 +948,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1014,7 +1014,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1201,9 +1201,9 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withSubject("ExtraEntry3") .build(); - WorkflowItem witem1 = claimedTask1.getWorkflowItem(); - WorkflowItem witem2 = claimedTask2.getWorkflowItem(); - WorkflowItem witem3 = claimedTask3.getWorkflowItem(); + XmlWorkflowItem witem1 = claimedTask1.getWorkflowItem(); + XmlWorkflowItem witem2 = claimedTask2.getWorkflowItem(); + XmlWorkflowItem witem3 = claimedTask3.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1340,9 +1340,9 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withSubject("ExtraEntry3") .build(); - WorkflowItem witem1 = claimedTask1.getWorkflowItem(); - WorkflowItem witem2 = claimedTask2.getWorkflowItem(); - WorkflowItem witem3 = claimedTask3.getWorkflowItem(); + XmlWorkflowItem witem1 = claimedTask1.getWorkflowItem(); + XmlWorkflowItem witem2 = claimedTask2.getWorkflowItem(); + XmlWorkflowItem witem3 = claimedTask3.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1407,7 +1407,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); Item item = witem.getItem(); context.restoreAuthSystemState(); @@ -1483,7 +1483,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); Item item = witem.getItem(); context.restoreAuthSystemState(); @@ -1548,7 +1548,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); Item item = witem.getItem(); context.restoreAuthSystemState(); @@ -1657,7 +1657,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); Item item = witem.getItem(); context.restoreAuthSystemState(); @@ -1726,7 +1726,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); Item item = witem.getItem(); context.restoreAuthSystemState(); @@ -1800,7 +1800,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2029,7 +2029,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2051,7 +2051,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "reviewstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2074,7 +2074,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { Matchers.allOf( hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2144,7 +2144,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2163,7 +2163,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "reviewstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2186,7 +2186,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { Matchers.allOf( hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2243,7 +2243,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2265,7 +2265,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "editstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2288,7 +2288,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { Matchers.allOf( hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2356,7 +2356,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2378,7 +2378,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "editstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2401,7 +2401,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { Matchers.allOf( hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2464,7 +2464,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2486,7 +2486,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "finaleditstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2509,7 +2509,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { Matchers.allOf( hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2572,7 +2572,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2594,7 +2594,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "finaleditstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2617,7 +2617,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { Matchers.allOf( hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2670,7 +2670,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2692,7 +2692,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "finaleditstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2715,7 +2715,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { Matchers.allOf( hasJsonPath("$._links.self.href", Matchers.containsString("/api/workflow/claimedtasks/")), hasJsonPath("$.type", Matchers.is("claimedtask")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2782,7 +2782,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald").withAuthor("Doe, John") .withSubject("ExtraEntry") .build(); - WorkflowItem witem = poolTask.getWorkflowItem(); + XmlWorkflowItem witem = poolTask.getWorkflowItem(); poolTask.setStepID("editstep"); poolTask.setActionID("editaction"); @@ -2835,7 +2835,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -2854,7 +2854,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "editstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -2924,7 +2924,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .build(); claimedTask.setStepID("reviewstep"); claimedTask.setActionID("reviewaction"); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -2982,7 +2982,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { context.setCurrentUser(submitter); //3. create a workflowitem (so a pool task in step1) - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Test item full workflow") .withIssueDate("2019-03-06") .withSubject("ExtraEntry") @@ -3001,7 +3001,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( Matchers.allOf( Matchers.is(PoolTaskMatcher.matchPoolTask(null, "reviewstep")), - hasJsonPath("$._embedded.workflowitem", + hasJsonPath("$._embedded.workflowitem", Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( witem, "Test item full workflow", "2019-03-06", "ExtraEntry"))) )))) @@ -3076,7 +3076,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .build(); claimedTask.setStepID("editstep"); claimedTask.setActionID("editaction"); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); String reviewer1Token = getAuthToken(reviewer1.getEmail(), password); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowActionRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowActionRestRepositoryIT.java index 369d317698..884fc6cfa5 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowActionRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowActionRestRepositoryIT.java @@ -17,8 +17,8 @@ import org.dspace.app.rest.matcher.WorkflowActionMatcher; import org.dspace.app.rest.model.WorkflowActionRest; import org.dspace.app.rest.repository.WorkflowActionRestRepository; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; -import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; import org.hamcrest.Matchers; import org.junit.Test; @@ -30,7 +30,7 @@ import org.junit.Test; */ public class WorkflowActionRestRepositoryIT extends AbstractControllerIntegrationTest { - private XmlWorkflowFactory xmlWorkflowFactory = WorkflowServiceFactory.getInstance().getWorkflowFactory(); + private XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory(); private static final String WORKFLOW_ACTIONS_ENDPOINT = "/api/" + WorkflowActionRest.CATEGORY + "/" + WorkflowActionRest.NAME_PLURAL; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowDefinitionRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowDefinitionRestRepositoryIT.java index 7b20485daa..3f7ae74000 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowDefinitionRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowDefinitionRestRepositoryIT.java @@ -27,8 +27,8 @@ import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.content.Collection; import org.dspace.content.Community; -import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Workflow; import org.hamcrest.Matchers; import org.junit.Test; @@ -42,7 +42,7 @@ import org.junit.Test; public class WorkflowDefinitionRestRepositoryIT extends AbstractControllerIntegrationTest { private final XmlWorkflowFactory xmlWorkflowFactory - = WorkflowServiceFactory.getInstance().getWorkflowFactory(); + = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory(); private static final String WORKFLOW_DEFINITIONS_ENDPOINT = "/api/" + WorkflowDefinitionRest.CATEGORY + "/" + WorkflowDefinitionRest.NAME_PLURAL; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestRepositoryIT.java index 760e2df1a2..7a0fe01d4a 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestRepositoryIT.java @@ -54,10 +54,10 @@ import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; import org.dspace.eperson.EPerson; import org.dspace.services.ConfigurationService; -import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Ignore; @@ -112,17 +112,17 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT //2. Three workflow items in two different collections - WorkflowItem workflowItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem workflowItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .build(); - WorkflowItem workflowItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem workflowItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 2") .withIssueDate("2016-02-13") .build(); - WorkflowItem workflowItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem workflowItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 3") .withIssueDate("2016-02-13") .build(); @@ -167,17 +167,17 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(1, admin).build(); //2. Three workflow items in two different collections - WorkflowItem workflowItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem workflowItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .build(); - WorkflowItem workflowItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem workflowItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 2") .withIssueDate("2016-02-13") .build(); - WorkflowItem workflowItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem workflowItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 3") .withIssueDate("2016-02-13") .build(); @@ -237,18 +237,18 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT //2. Three workflow items in two different collections - WorkflowItem workflowItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem workflowItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .build(); // these two items will be visible individually to the user - WorkflowItem workflowItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem workflowItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 2") .withIssueDate("2016-02-13") .build(); - WorkflowItem workflowItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem workflowItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 3") .withIssueDate("2016-02-13") .build(); @@ -286,7 +286,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(1, admin).build(); //2. a workflow item - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -340,30 +340,30 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(3, reviewer3).build(); //2. three workflow items in the three collections (this will lead to pool task) - WorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .build(); - WorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 2") .build(); - WorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col3) + XmlWorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col3) .withTitle("Workflow Item 3") .build(); //3. Three claimed tasks (and corresponding workflowitems) ClaimedTask claimed1 = ClaimedTaskBuilder.createClaimedTask(context, col1, reviewer1).withTitle("Pool 1") .build(); - WorkflowItem wClaimed1 = claimed1.getWorkflowItem(); + XmlWorkflowItem wClaimed1 = claimed1.getWorkflowItem(); ClaimedTask claimed2 = ClaimedTaskBuilder.createClaimedTask(context, col2, reviewer2).withTitle("Pool 2") .build(); - WorkflowItem wClaimed2 = claimed2.getWorkflowItem(); + XmlWorkflowItem wClaimed2 = claimed2.getWorkflowItem(); ClaimedTask claimed3 = ClaimedTaskBuilder.createClaimedTask(context, col3, reviewer3).withTitle("Pool 3") .build(); - WorkflowItem wClaimed3 = claimed3.getWorkflowItem(); + XmlWorkflowItem wClaimed3 = claimed3.getWorkflowItem(); context.restoreAuthSystemState(); @@ -457,7 +457,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(1, admin).build(); //2. a workflow item - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -536,19 +536,19 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT //3. Two workflow items in two different collections - WorkflowItem workspaceItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem workspaceItem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .build(); - WorkflowItem workspaceItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem workspaceItem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 2") .withIssueDate("2016-02-13") .build(); //4. A workflowitem for the second submitter context.setCurrentUser(submitter2); - WorkflowItem workspaceItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem workspaceItem3 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 3") .withIssueDate("2016-02-13") .build(); @@ -634,7 +634,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT context.setCurrentUser(submitter); //3. a workflow item - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .build(); @@ -864,13 +864,13 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT context.setCurrentUser(submitter); //3. a workflow item will all the required fields - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .build(); //4. a workflow item without the dateissued required field - WorkflowItem witemMissingFields = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witemMissingFields = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .build(); @@ -927,7 +927,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .build(); claimedTask.setStepID("editstep"); claimedTask.setActionID("editaction"); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -988,7 +988,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT context.setCurrentUser(submitter); //3. a workflow item - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withSubject("ExtraEntry") @@ -1054,7 +1054,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .build(); claimedTask.setStepID("editstep"); claimedTask.setActionID("editaction"); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1123,7 +1123,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .build(); claimedTask.setStepID("editstep"); claimedTask.setActionID("editaction"); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); ClaimedTask claimedTask2 = ClaimedTaskBuilder.createClaimedTask(context, col1, eperson) .withTitle("Workflow Item 2") @@ -1135,7 +1135,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .build(); claimedTask2.setStepID("editstep"); claimedTask2.setActionID("editaction"); - WorkflowItem witemMultipleSubjects = claimedTask2.getWorkflowItem(); + XmlWorkflowItem witemMultipleSubjects = claimedTask2.getWorkflowItem(); ClaimedTask claimedTask3 = ClaimedTaskBuilder.createClaimedTask(context, col1, eperson) .withTitle("Workflow Item 3") @@ -1147,7 +1147,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .build(); claimedTask3.setStepID("editstep"); claimedTask3.setActionID("editaction"); - WorkflowItem witemWithTitleDateAndSubjects = claimedTask3.getWorkflowItem(); + XmlWorkflowItem witemWithTitleDateAndSubjects = claimedTask3.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1321,7 +1321,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .build(); claimedTask.setStepID("editstep"); claimedTask.setActionID("editaction"); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1391,7 +1391,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .build(); claimedTask.setStepID("editstep"); claimedTask.setActionID("editaction"); - WorkflowItem witem = claimedTask.getWorkflowItem(); + XmlWorkflowItem witem = claimedTask.getWorkflowItem(); context.restoreAuthSystemState(); @@ -1586,7 +1586,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(1, admin).build(); //2. a workflow item - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -1646,7 +1646,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT Item item = ItemBuilder.createItem(context, col1).build(); //2. a workspace item - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -1676,7 +1676,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(1, admin).build(); - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -1707,7 +1707,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(1, admin).build(); - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") @@ -1753,17 +1753,17 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(3, reviewer3).build(); //2. three workflow items in the three collections (this will lead to pool task) - WorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem1 = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2016-02-13") .build(); - WorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) + XmlWorkflowItem witem2 = WorkflowItemBuilder.createWorkflowItem(context, col2) .withTitle("Workflow Item 2") .withIssueDate("2016-02-13") .build(); - WorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col3) + XmlWorkflowItem witem3 = WorkflowItemBuilder.createWorkflowItem(context, col3) .withTitle("Workflow Item 3") .withIssueDate("2016-02-13") .build(); @@ -1835,7 +1835,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT .withWorkflowGroup(1, admin).build(); //2. a workflow item - WorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) .withTitle("Workflow Item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowStepRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowStepRestRepositoryIT.java index 8399ab9373..a9a5b12d94 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowStepRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowStepRestRepositoryIT.java @@ -15,8 +15,8 @@ import org.dspace.app.rest.matcher.WorkflowStepMatcher; import org.dspace.app.rest.model.WorkflowStepRest; import org.dspace.app.rest.repository.WorkflowStepRestRepository; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; -import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Step; import org.hamcrest.Matchers; import org.junit.Test; @@ -28,7 +28,7 @@ import org.junit.Test; */ public class WorkflowStepRestRepositoryIT extends AbstractControllerIntegrationTest { - private XmlWorkflowFactory xmlWorkflowFactory = WorkflowServiceFactory.getInstance().getWorkflowFactory(); + private XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory(); private static final String WORKFLOW_ACTIONS_ENDPOINT = "/api/" + WorkflowStepRest.CATEGORY + "/" + WorkflowStepRest.NAME_PLURAL; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ReinstateFeatureRestIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ReinstateFeatureRestIT.java index 8c630a6795..870937160a 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ReinstateFeatureRestIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ReinstateFeatureRestIT.java @@ -30,7 +30,7 @@ import org.dspace.content.Community; import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; import org.dspace.services.ConfigurationService; -import org.dspace.workflow.WorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; @@ -239,7 +239,7 @@ public class ReinstateFeatureRestIT extends AbstractControllerIntegrationTest { Item archivedItem = ItemBuilder.createItem(context, col).withTitle("Item already in archive").build(); WorkspaceItem wsItem = WorkspaceItemBuilder.createWorkspaceItem(context, col).withTitle("A workspace item") .build(); - WorkflowItem wfItem = WorkflowItemBuilder.createWorkflowItem(context, col).withTitle("A workflow item").build(); + XmlWorkflowItem wfItem = WorkflowItemBuilder.createWorkflowItem(context, col).withTitle("A workflow item").build(); context.restoreAuthSystemState(); ItemRest archivedItemRest = itemConverter.convert(archivedItem, Projection.DEFAULT); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/WithdrawFeatureRestIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/WithdrawFeatureRestIT.java index e0d00fa63a..04dafbade7 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/WithdrawFeatureRestIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/WithdrawFeatureRestIT.java @@ -30,7 +30,7 @@ import org.dspace.content.Community; import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; import org.dspace.services.ConfigurationService; -import org.dspace.workflow.WorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; @@ -240,7 +240,7 @@ public class WithdrawFeatureRestIT extends AbstractControllerIntegrationTest { .build(); WorkspaceItem wsItem = WorkspaceItemBuilder.createWorkspaceItem(context, col).withTitle("A workspace item") .build(); - WorkflowItem wfItem = WorkflowItemBuilder.createWorkflowItem(context, col).withTitle("A workflow item").build(); + XmlWorkflowItem wfItem = WorkflowItemBuilder.createWorkflowItem(context, col).withTitle("A workflow item").build(); context.restoreAuthSystemState(); ItemRest withdrawnItemRest = itemConverter.convert(withdrawnItem, Projection.DEFAULT); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/eperson/DeleteEPersonSubmitterIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/eperson/DeleteEPersonSubmitterIT.java index 304ed5033b..e280bffdef 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/eperson/DeleteEPersonSubmitterIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/eperson/DeleteEPersonSubmitterIT.java @@ -50,10 +50,10 @@ import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.versioning.Version; import org.dspace.versioning.factory.VersionServiceFactory; import org.dspace.versioning.service.VersioningService; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflow.WorkflowService; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.xmlworkflow.service.XmlWorkflowService; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; @@ -68,9 +68,9 @@ public class DeleteEPersonSubmitterIT extends AbstractControllerIntegrationTest protected InstallItemService installItemService = ContentServiceFactory.getInstance().getInstallItemService(); protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance() .getWorkspaceItemService(); - protected WorkflowService workflowService = WorkflowServiceFactory.getInstance().getWorkflowService(); - protected WorkflowItemService workflowItemService = WorkflowServiceFactory.getInstance() - .getWorkflowItemService(); + protected XmlWorkflowService xmlWorkflowService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); + protected XmlWorkflowItemService xmlWorkflowItemService = XmlWorkflowServiceFactory.getInstance() + .getXmlWorkflowItemService(); protected VersioningService versioningService = VersionServiceFactory.getInstance().getVersionService(); protected RequestItemAuthorExtractor requestItemAuthorExtractor = @@ -315,7 +315,7 @@ public class DeleteEPersonSubmitterIT extends AbstractControllerIntegrationTest .withWorkflowGroup(1, workflowUser) .build(); - WorkflowItem workflowItem = WorkflowItemBuilder.createWorkflowItem(context, collection) + XmlWorkflowItem workflowItem = WorkflowItemBuilder.createWorkflowItem(context, collection) .withSubmitter(submitter) .withTitle("Test Item") .withIssueDate("2019-03-06") diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowDefinitionMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowDefinitionMatcher.java index 268948ad2c..02712ee3a2 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowDefinitionMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowDefinitionMatcher.java @@ -15,8 +15,8 @@ import static org.hamcrest.Matchers.is; import java.util.UUID; import org.dspace.app.rest.model.WorkflowDefinitionRest; -import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Workflow; import org.hamcrest.Matcher; import org.hamcrest.Matchers; @@ -26,7 +26,7 @@ import org.hamcrest.Matchers; */ public class WorkflowDefinitionMatcher { - private static XmlWorkflowFactory xmlWorkflowFactory = WorkflowServiceFactory.getInstance().getWorkflowFactory(); + private static XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory(); private static final String WORKFLOW_DEFINITIONS_ENDPOINT = "/api/" + WorkflowDefinitionRest.CATEGORY + "/" + WorkflowDefinitionRest.NAME_PLURAL + "/"; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowItemMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowItemMatcher.java index 7fd8fa0926..7a1b0fcb92 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowItemMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/WorkflowItemMatcher.java @@ -14,7 +14,7 @@ import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.startsWith; -import org.dspace.workflow.WorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.hamcrest.Matcher; /** @@ -38,8 +38,8 @@ public class WorkflowItemMatcher { * the dc.date.issued * @return */ - public static Matcher matchItemWithTitleAndDateIssued(WorkflowItem witem, String title, - String dateIssued) { + public static Matcher matchItemWithTitleAndDateIssued(XmlWorkflowItem witem, String title, + String dateIssued) { return allOf( // Check workflowitem properties matchProperties(witem), @@ -64,9 +64,9 @@ public class WorkflowItemMatcher { * * @return */ - public static Matcher matchItemWithTitleAndDateIssuedAndSubject(WorkflowItem witem, String title, - String dateIssued, - String subject) { + public static Matcher matchItemWithTitleAndDateIssuedAndSubject(XmlWorkflowItem witem, String title, + String dateIssued, + String subject) { return allOf( // Check workspaceitem properties matchProperties(witem), @@ -88,7 +88,7 @@ public class WorkflowItemMatcher { * the workflowitem * @return */ - public static Matcher matchProperties(WorkflowItem witem) { + public static Matcher matchProperties(XmlWorkflowItem witem) { return allOf( witem != null ? hasJsonPath("$.id", is(witem.getID())) : hasJsonPath("$.id"), hasJsonPath("$.type", is("workflowitem")) @@ -102,7 +102,7 @@ public class WorkflowItemMatcher { * the workflowitem * @return */ - public static Matcher matchLinks(WorkflowItem witem) { + public static Matcher matchLinks(XmlWorkflowItem witem) { return allOf( witem != null ? hasJsonPath("$._links.self.href", diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java b/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java index 3beea04d95..cc06e3398d 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java @@ -24,9 +24,9 @@ import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.WorkspaceItemService; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.swordapp.server.AuthCredentials; import org.swordapp.server.CollectionListManager; import org.swordapp.server.SwordAuthException; @@ -39,8 +39,8 @@ public class CollectionListManagerDSpace extends DSpaceSwordAPI protected WorkspaceItemService workspaceItemService = ContentServiceFactory .getInstance().getWorkspaceItemService(); - protected WorkflowItemService workflowItemService = WorkflowServiceFactory - .getInstance().getWorkflowItemService(); + protected XmlWorkflowItemService workflowItemService = XmlWorkflowServiceFactory + .getInstance().getXmlWorkflowItemService(); @Override public Feed listCollectionContents(IRI colIRI, @@ -144,8 +144,8 @@ public class CollectionListManagerDSpace extends DSpaceSwordAPI List wfis = workflowItemService.findBySubmitter(sc.getContext(), person); for (Object found : wfis) { - if (found instanceof WorkflowItem) { - WorkflowItem wfi = (WorkflowItem) found; + if (found instanceof XmlWorkflowItem) { + XmlWorkflowItem wfi = (XmlWorkflowItem) found; Item item = wfi.getItem(); // check for the wfi collection diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/ContainerManagerDSpace.java b/dspace-swordv2/src/main/java/org/dspace/sword2/ContainerManagerDSpace.java index 9bb6eb8790..35991e1a32 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/ContainerManagerDSpace.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/ContainerManagerDSpace.java @@ -25,9 +25,9 @@ import org.dspace.content.service.WorkspaceItemService; import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.core.LogManager; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.swordapp.server.AuthCredentials; import org.swordapp.server.ContainerManager; import org.swordapp.server.Deposit; @@ -44,8 +44,8 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI protected AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService(); - protected WorkflowItemService workflowItemService = - WorkflowServiceFactory.getInstance().getWorkflowItemService(); + protected XmlWorkflowItemService workflowItemService = + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService(); protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); @@ -757,7 +757,7 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI WorkspaceItem wsi = wft.getWorkspaceItem(context, item); workspaceItemService.deleteAll(context, wsi); } else if (wft.isItemInWorkflow(context, item)) { - WorkflowItem wfi = wft.getWorkflowItem(context, item); + XmlWorkflowItem wfi = wft.getWorkflowItem(context, item); workflowItemService.deleteWrapper(context, wfi); } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowTools.java b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowTools.java index bb20866447..30bcfd4111 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowTools.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowTools.java @@ -19,20 +19,20 @@ import org.dspace.core.Context; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.workflow.WorkflowException; -import org.dspace.workflow.WorkflowItem; -import org.dspace.workflow.WorkflowItemService; -import org.dspace.workflow.WorkflowService; -import org.dspace.workflow.factory.WorkflowServiceFactory; +import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.xmlworkflow.service.XmlWorkflowService; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; public class WorkflowTools { protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); - protected WorkflowItemService workflowItemService = - WorkflowServiceFactory.getInstance().getWorkflowItemService(); + protected XmlWorkflowItemService workflowItemService = + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService(); - protected WorkflowService workflowService = - WorkflowServiceFactory.getInstance().getWorkflowService(); + protected XmlWorkflowService workflowService = + XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); protected ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); @@ -88,7 +88,7 @@ public class WorkflowTools { * @return workflow item * @throws DSpaceSwordException can be thrown by the internals of the DSpace SWORD implementation */ - public WorkflowItem getWorkflowItem(Context context, Item item) + public XmlWorkflowItem getWorkflowItem(Context context, Item item) throws DSpaceSwordException { try { return workflowItemService.findByItem(context, item); @@ -154,7 +154,7 @@ public class WorkflowTools { throws DSpaceSwordException { try { // find the item in the workflow if it exists - WorkflowItem wfi = this.getWorkflowItem(context, item); + XmlWorkflowItem wfi = this.getWorkflowItem(context, item); // abort the workflow if (wfi != null) { diff --git a/dspace/config/hibernate.cfg.xml b/dspace/config/hibernate.cfg.xml index 5ac79c144d..39f5a11378 100644 --- a/dspace/config/hibernate.cfg.xml +++ b/dspace/config/hibernate.cfg.xml @@ -80,7 +80,7 @@ - + diff --git a/dspace/config/spring/api/core-dao-services.xml b/dspace/config/spring/api/core-dao-services.xml index e8cfdf3be9..c534b0075c 100644 --- a/dspace/config/spring/api/core-dao-services.xml +++ b/dspace/config/spring/api/core-dao-services.xml @@ -58,7 +58,7 @@ - + diff --git a/dspace/config/spring/api/core-factory-services.xml b/dspace/config/spring/api/core-factory-services.xml index 4883b76da2..2712ad21d0 100644 --- a/dspace/config/spring/api/core-factory-services.xml +++ b/dspace/config/spring/api/core-factory-services.xml @@ -44,7 +44,7 @@ - + diff --git a/dspace/config/spring/api/core-services.xml b/dspace/config/spring/api/core-services.xml index 57edea3ef1..a0da450765 100644 --- a/dspace/config/spring/api/core-services.xml +++ b/dspace/config/spring/api/core-services.xml @@ -110,8 +110,8 @@ - - + + diff --git a/dspace/config/spring/api/discovery.xml b/dspace/config/spring/api/discovery.xml index 7245e14ca1..76e5a07239 100644 --- a/dspace/config/spring/api/discovery.xml +++ b/dspace/config/spring/api/discovery.xml @@ -702,7 +702,7 @@ - search.resourcetype:Item OR search.resourcetype:WorkspaceItem OR search.resourcetype:WorkflowItem + search.resourcetype:Item OR search.resourcetype:WorkspaceItem OR search.resourcetype:XmlWorkflowItem @@ -855,7 +855,7 @@ queries done by discovery for this configuration --> - search.resourcetype:WorkflowItem + search.resourcetype:XmlWorkflowItem From 8306d303410d1eb75bc1a1bbe773065693c742f1 Mon Sep 17 00:00:00 2001 From: Samuel Date: Tue, 23 Feb 2021 20:34:16 +0100 Subject: [PATCH 082/179] Remove Traditional/Basic Workflow from codebase and database - add TODO comment to Curation --- dspace-api/src/main/java/org/dspace/curate/Curation.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/curate/Curation.java b/dspace-api/src/main/java/org/dspace/curate/Curation.java index 4fcb580b0f..a01c731189 100644 --- a/dspace-api/src/main/java/org/dspace/curate/Curation.java +++ b/dspace-api/src/main/java/org/dspace/curate/Curation.java @@ -159,6 +159,8 @@ public class Curation extends DSpaceRunnable { } curator.curate(context, entry.getObjectId()); } else { + // TODO: Remove this exception once curation tasks are supported by configurable workflow + // e.g. see https://github.com/DSpace/DSpace/pull/3157 throw new IllegalArgumentException("curation for workflow items is no longer supported"); } } From a752f7638ef47d54a278f751a79d24fb882a7d92 Mon Sep 17 00:00:00 2001 From: Samuel Date: Tue, 23 Feb 2021 20:43:50 +0100 Subject: [PATCH 083/179] Remove Traditional/Basic Workflow from codebase and database - fix checkstyle issues --- .../dspace/app/bulkedit/MetadataImport.java | 3 +- .../org/dspace/content/ItemServiceImpl.java | 3 +- .../org/dspace/discovery/SearchUtils.java | 3 +- .../java/org/dspace/eperson/EPersonTest.java | 28 ++++++++++++------- .../authorization/ReinstateFeatureRestIT.java | 4 +-- .../authorization/WithdrawFeatureRestIT.java | 4 +-- 6 files changed, 28 insertions(+), 17 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/bulkedit/MetadataImport.java b/dspace-api/src/main/java/org/dspace/app/bulkedit/MetadataImport.java index f94fc67f2b..5fe0f887cd 100644 --- a/dspace-api/src/main/java/org/dspace/app/bulkedit/MetadataImport.java +++ b/dspace-api/src/main/java/org/dspace/app/bulkedit/MetadataImport.java @@ -570,7 +570,8 @@ public class MetadataImport extends DSpaceRunnable getAllDiscoveryConfigurations(XmlWorkflowItem witem) throws SQLException { + public static List getAllDiscoveryConfigurations(XmlWorkflowItem witem) + throws SQLException { List collections = new ArrayList(); collections.add(witem.getCollection()); return getAllDiscoveryConfigurations("workflow", collections, witem.getItem()); diff --git a/dspace-api/src/test/java/org/dspace/eperson/EPersonTest.java b/dspace-api/src/test/java/org/dspace/eperson/EPersonTest.java index ad1c1aee48..4145695509 100644 --- a/dspace-api/src/test/java/org/dspace/eperson/EPersonTest.java +++ b/dspace-api/src/test/java/org/dspace/eperson/EPersonTest.java @@ -50,16 +50,24 @@ import org.junit.Test; */ public class EPersonTest extends AbstractUnitTest { - protected EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); - protected GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - protected CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService(); - protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService(); - protected ItemService itemService = ContentServiceFactory.getInstance().getItemService(); - protected InstallItemService installItemService = ContentServiceFactory.getInstance().getInstallItemService(); - protected XmlWorkflowItemService workflowItemService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService(); - protected XmlWorkflowService workflowService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); - protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance() - .getWorkspaceItemService(); + protected EPersonService ePersonService + = EPersonServiceFactory.getInstance().getEPersonService(); + protected GroupService groupService + = EPersonServiceFactory.getInstance().getGroupService(); + protected CommunityService communityService + = ContentServiceFactory.getInstance().getCommunityService(); + protected CollectionService collectionService + = ContentServiceFactory.getInstance().getCollectionService(); + protected ItemService itemService + = ContentServiceFactory.getInstance().getItemService(); + protected InstallItemService installItemService + = ContentServiceFactory.getInstance().getInstallItemService(); + protected XmlWorkflowItemService workflowItemService + = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService(); + protected XmlWorkflowService workflowService + = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); + protected WorkspaceItemService workspaceItemService + = ContentServiceFactory.getInstance().getWorkspaceItemService(); private Community community = null; private Collection collection = null; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ReinstateFeatureRestIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ReinstateFeatureRestIT.java index 870937160a..b36a9c2487 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ReinstateFeatureRestIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ReinstateFeatureRestIT.java @@ -7,6 +7,7 @@ */ package org.dspace.app.rest.authorization; +import static org.dspace.builder.WorkflowItemBuilder.createWorkflowItem; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.is; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -23,7 +24,6 @@ import org.dspace.app.rest.utils.Utils; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.ItemBuilder; -import org.dspace.builder.WorkflowItemBuilder; import org.dspace.builder.WorkspaceItemBuilder; import org.dspace.content.Collection; import org.dspace.content.Community; @@ -239,7 +239,7 @@ public class ReinstateFeatureRestIT extends AbstractControllerIntegrationTest { Item archivedItem = ItemBuilder.createItem(context, col).withTitle("Item already in archive").build(); WorkspaceItem wsItem = WorkspaceItemBuilder.createWorkspaceItem(context, col).withTitle("A workspace item") .build(); - XmlWorkflowItem wfItem = WorkflowItemBuilder.createWorkflowItem(context, col).withTitle("A workflow item").build(); + XmlWorkflowItem wfItem = createWorkflowItem(context, col).withTitle("A workflow item").build(); context.restoreAuthSystemState(); ItemRest archivedItemRest = itemConverter.convert(archivedItem, Projection.DEFAULT); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/WithdrawFeatureRestIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/WithdrawFeatureRestIT.java index 04dafbade7..df1d8105dd 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/WithdrawFeatureRestIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/WithdrawFeatureRestIT.java @@ -7,6 +7,7 @@ */ package org.dspace.app.rest.authorization; +import static org.dspace.builder.WorkflowItemBuilder.createWorkflowItem; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.is; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -23,7 +24,6 @@ import org.dspace.app.rest.utils.Utils; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.ItemBuilder; -import org.dspace.builder.WorkflowItemBuilder; import org.dspace.builder.WorkspaceItemBuilder; import org.dspace.content.Collection; import org.dspace.content.Community; @@ -240,7 +240,7 @@ public class WithdrawFeatureRestIT extends AbstractControllerIntegrationTest { .build(); WorkspaceItem wsItem = WorkspaceItemBuilder.createWorkspaceItem(context, col).withTitle("A workspace item") .build(); - XmlWorkflowItem wfItem = WorkflowItemBuilder.createWorkflowItem(context, col).withTitle("A workflow item").build(); + XmlWorkflowItem wfItem = createWorkflowItem(context, col).withTitle("A workflow item").build(); context.restoreAuthSystemState(); ItemRest withdrawnItemRest = itemConverter.convert(withdrawnItem, Projection.DEFAULT); From b779b91e54e22c5b4d01f886aee4228b7f94f2ff Mon Sep 17 00:00:00 2001 From: Samuel Date: Wed, 24 Feb 2021 15:31:29 +0100 Subject: [PATCH 084/179] Remove Traditional/Basic Workflow from codebase and database - restore in-between layer --- .../dspace/app/bulkedit/MetadataImport.java | 11 +- .../app/itemimport/ItemImportServiceImpl.java | 8 +- .../authorize/AuthorizeServiceImpl.java | 4 +- .../dspace/content/CollectionServiceImpl.java | 6 +- .../org/dspace/content/ItemServiceImpl.java | 9 +- .../org/dspace/content/WorkspaceItem.java | 4 +- .../content/WorkspaceItemServiceImpl.java | 8 +- .../factory/ContentServiceFactory.java | 4 +- .../packager/AbstractMETSIngester.java | 4 +- .../dspace/content/packager/PackageUtils.java | 6 +- .../content/service/WorkspaceItemService.java | 4 +- .../org/dspace/discovery/SearchUtils.java | 5 +- .../dspace/eperson/EPersonServiceImpl.java | 6 +- .../java/org/dspace/health/ItemCheck.java | 4 +- .../dspace/identifier/doi/DOIConsumer.java | 4 +- .../main/java/org/dspace/rdf/RDFConsumer.java | 8 +- .../dspace/storage/rdbms/DatabaseUtils.java | 6 +- .../DefaultItemVersionProvider.java | 4 +- .../versioning/VersioningServiceImpl.java | 8 +- .../org/dspace/workflow/WorkflowItem.java | 19 +++ .../dspace/workflow/WorkflowItemService.java | 109 +++++++++++++++ .../org/dspace/workflow/WorkflowService.java | 126 ++++++++++++++++++ .../factory/WorkflowServiceFactory.java | 30 +++++ .../java/org/dspace/workflow/package.html | 41 ++++++ .../factory/XmlWorkflowServiceFactory.java | 3 +- .../XmlWorkflowServiceFactoryImpl.java | 12 ++ .../migration/RestartWorkflow.java | 14 +- .../service/XmlWorkflowService.java | 103 +------------- .../storedcomponents/XmlWorkflowItem.java | 4 +- .../service/XmlWorkflowItemService.java | 91 +------------ .../java/org/dspace/eperson/EPersonTest.java | 38 +++--- .../identifier/DOIIdentifierProviderTest.java | 6 +- .../EZIDIdentifierProviderTest.java | 6 +- .../xmlworkflow/XmlWorkflowFactoryTest.java | 3 +- .../org/dspace/rest/CollectionsResource.java | 6 +- .../rest/CollectionGroupRestController.java | 4 +- .../repository/CollectionRestRepository.java | 4 +- .../WorkflowItemRestRepository.java | 4 +- .../WorkflowItemStepLinkRepository.java | 4 +- .../app/rest/submit/SubmissionService.java | 8 +- .../rest/CollectionGroupRestControllerIT.java | 4 +- .../app/rest/EPersonRestRepositoryIT.java | 4 +- .../app/rest/StatisticsRestRepositoryIT.java | 5 +- .../authorization/ReinstateFeatureRestIT.java | 6 +- .../authorization/WithdrawFeatureRestIT.java | 6 +- .../sword2/CollectionListManagerDSpace.java | 14 +- .../dspace/sword2/ContainerManagerDSpace.java | 12 +- .../java/org/dspace/sword2/WorkflowTools.java | 20 +-- 48 files changed, 483 insertions(+), 336 deletions(-) create mode 100644 dspace-api/src/main/java/org/dspace/workflow/WorkflowItem.java create mode 100644 dspace-api/src/main/java/org/dspace/workflow/WorkflowItemService.java create mode 100644 dspace-api/src/main/java/org/dspace/workflow/WorkflowService.java create mode 100644 dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactory.java create mode 100644 dspace-api/src/main/java/org/dspace/workflow/package.html diff --git a/dspace-api/src/main/java/org/dspace/app/bulkedit/MetadataImport.java b/dspace-api/src/main/java/org/dspace/app/bulkedit/MetadataImport.java index 5fe0f887cd..97a474db31 100644 --- a/dspace-api/src/main/java/org/dspace/app/bulkedit/MetadataImport.java +++ b/dspace-api/src/main/java/org/dspace/app/bulkedit/MetadataImport.java @@ -64,9 +64,9 @@ import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.utils.DSpace; import org.dspace.workflow.WorkflowException; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; -import org.dspace.xmlworkflow.service.XmlWorkflowService; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowService; +import org.dspace.workflow.factory.WorkflowServiceFactory; /** * Metadata importer to allow the batch import of metadata from a file @@ -370,7 +370,7 @@ public class MetadataImport extends DSpaceRunnable i } - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService().deleteCollection(context, collection); - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService().deleteByCollection(context, collection); + WorkflowServiceFactory.getInstance().getWorkflowService().deleteCollection(context, collection); + WorkflowServiceFactory.getInstance().getWorkflowItemService().deleteByCollection(context, collection); // get rid of the content count cache if it exists // Remove any Handle diff --git a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java index 23a9eaf8ac..a2e9553ba5 100644 --- a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java @@ -55,8 +55,8 @@ import org.dspace.identifier.IdentifierException; import org.dspace.identifier.service.IdentifierService; import org.dspace.services.ConfigurationService; import org.dspace.versioning.service.VersioningService; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.springframework.beans.factory.annotation.Autowired; /** @@ -106,7 +106,7 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl implements It @Autowired(required = true) protected WorkspaceItemService workspaceItemService; @Autowired(required = true) - protected XmlWorkflowItemService workflowItemService; + protected WorkflowItemService workflowItemService; @Autowired(required = true) protected RelationshipService relationshipService; @@ -1138,8 +1138,7 @@ prevent the generation of resource policy entry values with null dspace_object a .findByItem(context, item); if (inprogress == null) { - inprogress - = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService().findByItem(context, item); + inprogress = WorkflowServiceFactory.getInstance().getWorkflowItemService().findByItem(context, item); } if (inprogress != null) { diff --git a/dspace-api/src/main/java/org/dspace/content/WorkspaceItem.java b/dspace-api/src/main/java/org/dspace/content/WorkspaceItem.java index 4c01de3870..8049aa976c 100644 --- a/dspace-api/src/main/java/org/dspace/content/WorkspaceItem.java +++ b/dspace-api/src/main/java/org/dspace/content/WorkspaceItem.java @@ -28,7 +28,7 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.workflow.WorkflowItem; import org.hibernate.proxy.HibernateProxyHelper; /** @@ -90,7 +90,7 @@ public class WorkspaceItem * Protected constructor, create object using: * {@link org.dspace.content.service.WorkspaceItemService#create(Context, Collection, boolean)} * or - * {@link org.dspace.content.service.WorkspaceItemService#create(Context, XmlWorkflowItem)} + * {@link org.dspace.content.service.WorkspaceItemService#create(Context, WorkflowItem)} */ protected WorkspaceItem() { diff --git a/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java index 8fff023226..8fc302f8bf 100644 --- a/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java @@ -28,8 +28,8 @@ import org.dspace.core.Context; import org.dspace.core.LogManager; import org.dspace.eperson.EPerson; import org.dspace.event.Event; -import org.dspace.xmlworkflow.service.XmlWorkflowService; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -53,7 +53,7 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService { @Autowired(required = true) protected ItemService itemService; @Autowired(required = true) - protected XmlWorkflowService workflowService; + protected WorkflowService workflowService; protected WorkspaceItemServiceImpl() { @@ -138,7 +138,7 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService { } @Override - public WorkspaceItem create(Context c, XmlWorkflowItem workflowItem) throws SQLException, AuthorizeException { + public WorkspaceItem create(Context c, WorkflowItem workflowItem) throws SQLException, AuthorizeException { WorkspaceItem workspaceItem = workspaceItemDAO.create(c, new WorkspaceItem()); workspaceItem.setItem(workflowItem.getItem()); workspaceItem.setCollection(workflowItem.getCollection()); diff --git a/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java b/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java index 31c137fb64..4010e14861 100644 --- a/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java +++ b/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java @@ -34,7 +34,7 @@ import org.dspace.content.service.SiteService; import org.dspace.content.service.SupervisedItemService; import org.dspace.content.service.WorkspaceItemService; import org.dspace.services.factory.DSpaceServicesFactory; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.workflow.factory.WorkflowServiceFactory; /** * Abstract factory to get services for the content package, use ContentServiceFactory.getInstance() to retrieve an @@ -109,7 +109,7 @@ public abstract class ContentServiceFactory { if (inProgressSubmission instanceof WorkspaceItem) { return getWorkspaceItemService(); } else { - return XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService(); + return WorkflowServiceFactory.getInstance().getWorkflowItemService(); } } diff --git a/dspace-api/src/main/java/org/dspace/content/packager/AbstractMETSIngester.java b/dspace-api/src/main/java/org/dspace/content/packager/AbstractMETSIngester.java index 6304e88527..0db9a98b9a 100644 --- a/dspace-api/src/main/java/org/dspace/content/packager/AbstractMETSIngester.java +++ b/dspace-api/src/main/java/org/dspace/content/packager/AbstractMETSIngester.java @@ -49,7 +49,7 @@ import org.dspace.handle.service.HandleService; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.workflow.WorkflowException; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.jdom.Element; /** @@ -628,7 +628,7 @@ public abstract class AbstractMETSIngester extends AbstractPackageIngester { //We are probably dealing with an item that isn't archived yet InProgressSubmission inProgressSubmission = workspaceItemService.findByItem(context, item); if (inProgressSubmission == null) { - inProgressSubmission = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService() + inProgressSubmission = WorkflowServiceFactory.getInstance().getWorkflowItemService() .findByItem(context, item); } owningCollection = inProgressSubmission.getCollection(); diff --git a/dspace-api/src/main/java/org/dspace/content/packager/PackageUtils.java b/dspace-api/src/main/java/org/dspace/content/packager/PackageUtils.java index c050ce4b2a..e45aa7d699 100644 --- a/dspace-api/src/main/java/org/dspace/content/packager/PackageUtils.java +++ b/dspace-api/src/main/java/org/dspace/content/packager/PackageUtils.java @@ -52,8 +52,8 @@ import org.dspace.handle.factory.HandleServiceFactory; import org.dspace.handle.service.HandleService; import org.dspace.license.service.CreativeCommonsService; import org.dspace.workflow.WorkflowException; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; -import org.dspace.xmlworkflow.service.XmlWorkflowService; +import org.dspace.workflow.WorkflowService; +import org.dspace.workflow.factory.WorkflowServiceFactory; /** * Container class for code that is useful to many packagers. @@ -520,7 +520,7 @@ public class PackageUtils { } else if (params.workflowEnabled()) { // if we are treating package as a SIP, and we are told to respect workflows - XmlWorkflowService workflowService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); + WorkflowService workflowService = WorkflowServiceFactory.getInstance().getWorkflowService(); // Start an item workflow // (NOTICE: The specified handle is ignored, as Workflows *always* end in a new handle being assigned) return workflowService.startWithoutNotify(context, wsi).getItem(); diff --git a/dspace-api/src/main/java/org/dspace/content/service/WorkspaceItemService.java b/dspace-api/src/main/java/org/dspace/content/service/WorkspaceItemService.java index acf17fc8e3..3ee381706c 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/WorkspaceItemService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/WorkspaceItemService.java @@ -18,7 +18,7 @@ import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.workflow.WorkflowItem; /** * Service interface class for the WorkspaceItem object. @@ -55,7 +55,7 @@ public interface WorkspaceItemService extends InProgressSubmissionService getAllDiscoveryConfigurations(XmlWorkflowItem witem) - throws SQLException { + public static List getAllDiscoveryConfigurations(WorkflowItem witem) throws SQLException { List collections = new ArrayList(); collections.add(witem.getCollection()); return getAllDiscoveryConfigurations("workflow", collections, witem.getItem()); diff --git a/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java b/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java index 938a167f6f..00d6a8e5e7 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java @@ -49,6 +49,8 @@ import org.dspace.versioning.dao.VersionDAO; import org.dspace.versioning.factory.VersionServiceFactory; import org.dspace.versioning.service.VersionHistoryService; import org.dspace.versioning.service.VersioningService; +import org.dspace.workflow.WorkflowService; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; @@ -350,7 +352,7 @@ public class EPersonServiceImpl extends DSpaceObjectServiceImpl impleme poolTaskService.deleteByEperson(context, ePerson); } else if (StringUtils.equals(tableName, "cwf_workflowitemrole")) { WorkflowItemRoleService workflowItemRoleService = XmlWorkflowServiceFactory.getInstance() - .getWorkflowItemRoleService(); + .getWorkflowItemRoleService(); workflowItemRoleService.deleteByEPerson(context, ePerson); } else { log.warn("EPerson is referenced in table '" + tableName @@ -518,7 +520,7 @@ public class EPersonServiceImpl extends DSpaceObjectServiceImpl impleme tableList.add("resourcepolicy"); } - XmlWorkflowService workflowService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); + WorkflowService workflowService = WorkflowServiceFactory.getInstance().getWorkflowService(); List workflowConstraints = workflowService.getEPersonDeleteConstraints(context, ePerson); tableList.addAll(workflowConstraints); diff --git a/dspace-api/src/main/java/org/dspace/health/ItemCheck.java b/dspace-api/src/main/java/org/dspace/health/ItemCheck.java index 2204049bbb..d67be523a9 100644 --- a/dspace-api/src/main/java/org/dspace/health/ItemCheck.java +++ b/dspace-api/src/main/java/org/dspace/health/ItemCheck.java @@ -95,7 +95,7 @@ public class ItemCheck extends Check { ret += String.format( "\tWaiting for approval (workflow items): %d\n", - workflowItemService.countAll(context)); + workflowItemService.countAll(context)); } catch (SQLException e) { error(e); @@ -132,7 +132,7 @@ public class ItemCheck extends Check { sb.append(String.format("Count %-14s: %s\n", "Group", String.valueOf(groupService.countTotal(context)))); sb.append(String.format("Count %-14s: %s\n", "BasicWorkflowItem", - String.valueOf(workflowItemService.countAll(context)))); + String.valueOf(workflowItemService.countAll(context)))); sb.append(String.format("Count %-14s: %s\n", "WorkspaceItem", String.valueOf(workspaceItemService.countTotal(context)))); return sb.toString(); diff --git a/dspace-api/src/main/java/org/dspace/identifier/doi/DOIConsumer.java b/dspace-api/src/main/java/org/dspace/identifier/doi/DOIConsumer.java index ea8054aada..654d275d87 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/doi/DOIConsumer.java +++ b/dspace-api/src/main/java/org/dspace/identifier/doi/DOIConsumer.java @@ -19,7 +19,7 @@ import org.dspace.identifier.DOIIdentifierProvider; import org.dspace.identifier.IdentifierException; import org.dspace.identifier.IdentifierNotFoundException; import org.dspace.utils.DSpace; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.workflow.factory.WorkflowServiceFactory; /** * @author Pascal-Nicolas Becker (p dot becker at tu hyphen berlin dot de) @@ -64,7 +64,7 @@ public class DOIConsumer implements Consumer { Item item = (Item) dso; if (ContentServiceFactory.getInstance().getWorkspaceItemService().findByItem(ctx, item) != null - || XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService().findByItem(ctx, item) != null) { + || WorkflowServiceFactory.getInstance().getWorkflowItemService().findByItem(ctx, item) != null) { // ignore workflow and workspace items, DOI will be minted when item is installed return; } diff --git a/dspace-api/src/main/java/org/dspace/rdf/RDFConsumer.java b/dspace-api/src/main/java/org/dspace/rdf/RDFConsumer.java index ae11205a64..76ae0cd2d2 100644 --- a/dspace-api/src/main/java/org/dspace/rdf/RDFConsumer.java +++ b/dspace-api/src/main/java/org/dspace/rdf/RDFConsumer.java @@ -33,8 +33,8 @@ import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.event.Consumer; import org.dspace.event.Event; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.factory.WorkflowServiceFactory; /** * @author Pascal-Nicolas Becker (dspace -at- pascal -hyphen- becker -dot- de) @@ -49,7 +49,7 @@ public class RDFConsumer implements Consumer { protected BundleService bundleService; protected SiteService siteService; protected WorkspaceItemService workspaceItemService; - protected XmlWorkflowItemService workflowItemService; + protected WorkflowItemService workflowItemService; @Override public void initialize() throws Exception { @@ -57,7 +57,7 @@ public class RDFConsumer implements Consumer { bundleService = ContentServiceFactory.getInstance().getBundleService(); siteService = ContentServiceFactory.getInstance().getSiteService(); workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); - workflowItemService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService(); + workflowItemService = WorkflowServiceFactory.getInstance().getWorkflowItemService(); } @Override diff --git a/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseUtils.java b/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseUtils.java index 39e4b8abd0..5f8e72a535 100644 --- a/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseUtils.java +++ b/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseUtils.java @@ -32,7 +32,7 @@ import org.dspace.discovery.IndexingService; import org.dspace.discovery.SearchServiceException; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.flywaydb.core.Flyway; import org.flywaydb.core.api.FlywayException; import org.flywaydb.core.api.MigrationInfo; @@ -557,8 +557,8 @@ public class DatabaseUtils { scriptLocations.add("classpath:org/dspace/storage/rdbms/migration"); //Add all potential workflow migration paths - List workflowFlywayMigrationLocations = XmlWorkflowServiceFactory.getInstance() - .getXmlWorkflowService() + List workflowFlywayMigrationLocations = WorkflowServiceFactory.getInstance() + .getWorkflowService() .getFlywayMigrationLocations(); scriptLocations.addAll(workflowFlywayMigrationLocations); diff --git a/dspace-api/src/main/java/org/dspace/versioning/DefaultItemVersionProvider.java b/dspace-api/src/main/java/org/dspace/versioning/DefaultItemVersionProvider.java index 9934ca5085..7903a49c31 100644 --- a/dspace-api/src/main/java/org/dspace/versioning/DefaultItemVersionProvider.java +++ b/dspace-api/src/main/java/org/dspace/versioning/DefaultItemVersionProvider.java @@ -22,7 +22,7 @@ import org.dspace.identifier.IdentifierException; import org.dspace.identifier.service.IdentifierService; import org.dspace.versioning.service.VersionHistoryService; import org.dspace.versioning.service.VersioningService; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; +import org.dspace.workflow.WorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -37,7 +37,7 @@ public class DefaultItemVersionProvider extends AbstractVersionProvider implemen @Autowired(required = true) protected WorkspaceItemService workspaceItemService; @Autowired(required = true) - protected XmlWorkflowItemService workflowItemService; + protected WorkflowItemService workflowItemService; @Autowired(required = true) protected VersionHistoryService versionHistoryService; @Autowired(required = true) diff --git a/dspace-api/src/main/java/org/dspace/versioning/VersioningServiceImpl.java b/dspace-api/src/main/java/org/dspace/versioning/VersioningServiceImpl.java index 060bc678f6..ee6adf9098 100644 --- a/dspace-api/src/main/java/org/dspace/versioning/VersioningServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/versioning/VersioningServiceImpl.java @@ -21,8 +21,8 @@ import org.dspace.core.Context; import org.dspace.versioning.dao.VersionDAO; import org.dspace.versioning.service.VersionHistoryService; import org.dspace.versioning.service.VersioningService; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -42,7 +42,7 @@ public class VersioningServiceImpl implements VersioningService { @Autowired(required = true) private WorkspaceItemService workspaceItemService; @Autowired(required = true) - protected XmlWorkflowItemService workflowItemService; + protected WorkflowItemService workflowItemService; private DefaultItemVersionProvider provider; @@ -139,7 +139,7 @@ public class VersioningServiceImpl implements VersioningService { if (wsi != null) { workspaceItemService.deleteAll(c, wsi); } else { - XmlWorkflowItem wfi = workflowItemService.findByItem(c, item); + WorkflowItem wfi = workflowItemService.findByItem(c, item); if (wfi != null) { workflowItemService.delete(c, wfi); } diff --git a/dspace-api/src/main/java/org/dspace/workflow/WorkflowItem.java b/dspace-api/src/main/java/org/dspace/workflow/WorkflowItem.java new file mode 100644 index 0000000000..9f8e8e4a19 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/workflow/WorkflowItem.java @@ -0,0 +1,19 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.workflow; + +import org.dspace.content.InProgressSubmission; + +/** + * Interface representing a workflowitem, each workflowItem implementation must implement this interface. + * + * @author kevinvandevelde at atmire.com + */ +public interface WorkflowItem extends InProgressSubmission { + +} diff --git a/dspace-api/src/main/java/org/dspace/workflow/WorkflowItemService.java b/dspace-api/src/main/java/org/dspace/workflow/WorkflowItemService.java new file mode 100644 index 0000000000..48ee20b9ad --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/workflow/WorkflowItemService.java @@ -0,0 +1,109 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.workflow; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.List; + +import org.dspace.authorize.AuthorizeException; +import org.dspace.content.Collection; +import org.dspace.content.Item; +import org.dspace.content.service.InProgressSubmissionService; +import org.dspace.core.Context; +import org.dspace.eperson.EPerson; + +/** + * Service interface class for the Workflow items. + * All WorkflowItem service classes should implement this class since it offers some basic methods which all + * WorkflowItems + * are required to have. + * + * @author kevinvandevelde at atmire.com + */ +public interface WorkflowItemService extends InProgressSubmissionService { + + public T create(Context context, Item item, Collection collection) throws SQLException, AuthorizeException; + + /** + * Get a workflow item from the database. + * + * @param context The relevant DSpace Context. + * @param id ID of the workflow item + * @return the workflow item, or null if the ID is invalid. + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + public T find(Context context, int id) throws SQLException; + + /** + * return all workflowitems + * + * @param context The relevant DSpace Context. + * @return List of all workflowItems in system + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + public List findAll(Context context) throws SQLException; + + /** + * Get all workflow items for a particular collection. + * + * @param context The relevant DSpace Context. + * @param collection the collection + * @return array of the corresponding workflow items + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + public List findByCollection(Context context, Collection collection) throws SQLException; + + /** + * Check to see if a particular item is currently under Workflow. + * If so, its WorkflowItem is returned. If not, null is returned + * + * @param context The relevant DSpace Context. + * @param item the item + * @return workflow item corresponding to the item, or null + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + public T findByItem(Context context, Item item) throws SQLException; + + /** + * Get all workflow items that were original submissions by a particular + * e-person. + * + * @param context The relevant DSpace Context. + * @param ep the eperson + * @return the corresponding workflow items + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + public List findBySubmitter(Context context, EPerson ep) throws SQLException; + + /** + * Delete all workflow items present in the specified collection. + * + * @param context The relevant DSpace Context. + * @param collection the containing collection + * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. + * @throws SQLException An exception that provides information on a database access error or other errors. + * @throws AuthorizeException Exception indicating the current user of the context does not have permission + * to perform a particular action. + */ + public void deleteByCollection(Context context, Collection collection) + throws SQLException, IOException, AuthorizeException; + + /** + * Delete the specified workflow item. + * + * @param context The relevant DSpace Context. + * @param workflowItem which workflow item to delete + * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. + * @throws SQLException An exception that provides information on a database access error or other errors. + * @throws AuthorizeException Exception indicating the current user of the context does not have permission + * to perform a particular action. + */ + public void delete(Context context, T workflowItem) throws SQLException, AuthorizeException, IOException; + +} diff --git a/dspace-api/src/main/java/org/dspace/workflow/WorkflowService.java b/dspace-api/src/main/java/org/dspace/workflow/WorkflowService.java new file mode 100644 index 0000000000..ced074d71d --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/workflow/WorkflowService.java @@ -0,0 +1,126 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.workflow; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.List; + +import org.dspace.authorize.AuthorizeException; +import org.dspace.content.Collection; +import org.dspace.content.WorkspaceItem; +import org.dspace.core.Context; +import org.dspace.eperson.EPerson; +import org.dspace.eperson.Group; +import org.dspace.xmlworkflow.WorkflowConfigurationException; + +/** + * Service interface class for the WorkflowService framework. + * All WorkflowServices service classes should implement this class since it offers some basic methods which all + * Workflows + * are required to have. + * + * @param some implementation of workflow item. + * @author kevinvandevelde at atmire.com + */ +public interface WorkflowService { + + + /** + * startWorkflow() begins a workflow - in a single transaction do away with + * the PersonalWorkspace entry and turn it into a WorkflowItem. + * + * @param context The relevant DSpace Context. + * @param wsi The WorkspaceItem to convert to a workflow item + * @return The resulting workflow item + * @throws SQLException An exception that provides information on a database access error or other errors. + * @throws AuthorizeException Exception indicating the current user of the context does not have permission + * to perform a particular action. + * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. + * @throws WorkflowException if workflow error + */ + public T start(Context context, WorkspaceItem wsi) + throws SQLException, AuthorizeException, IOException, WorkflowException; + + /** + * startWithoutNotify() starts the workflow normally, but disables + * notifications (useful for large imports,) for the first workflow step - + * subsequent notifications happen normally + * + * @param c The relevant DSpace Context. + * @param wsi workspace item + * @return the resulting workflow item. + * @throws SQLException An exception that provides information on a database access error or other errors. + * @throws AuthorizeException Exception indicating the current user of the context does not have permission + * to perform a particular action. + * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. + * @throws WorkflowException if workflow error + */ + public T startWithoutNotify(Context c, WorkspaceItem wsi) + throws SQLException, AuthorizeException, IOException, WorkflowException; + + /** + * abort() aborts a workflow, completely deleting it (administrator do this) + * (it will basically do a reject from any state - the item ends up back in + * the user's PersonalWorkspace + * + * @param c The relevant DSpace Context. + * @param wi WorkflowItem to operate on + * @param e EPerson doing the operation + * @return workspace item returned to workspace + * @throws SQLException An exception that provides information on a database access error or other errors. + * @throws AuthorizeException Exception indicating the current user of the context does not have permission + * to perform a particular action. + * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. + */ + public WorkspaceItem abort(Context c, T wi, EPerson e) throws SQLException, AuthorizeException, IOException; + + /** + * Deletes workflow task item in correct order. + * + * @param c The relevant DSpace Context. + * @param wi The WorkflowItem that shall be deleted. + * @param e Admin that deletes this workflow task and item (for logging + * @throws SQLException An exception that provides information on a database access error or other errors. + * @throws AuthorizeException Exception indicating the current user of the context does not have permission + * to perform a particular action. + * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. + */ + public void deleteWorkflowByWorkflowItem(Context c, T wi, EPerson e) + throws SQLException, AuthorizeException, IOException; + + public WorkspaceItem sendWorkflowItemBackSubmission(Context c, T workflowItem, EPerson e, String provenance, + String rejection_message) + throws SQLException, AuthorizeException, IOException; + + public String getMyDSpaceLink(); + + public void deleteCollection(Context context, Collection collection) + throws SQLException, IOException, AuthorizeException; + + public List getEPersonDeleteConstraints(Context context, EPerson ePerson) throws SQLException; + + public Group getWorkflowRoleGroup(Context context, Collection collection, String roleName, Group roleGroup) + throws SQLException, IOException, WorkflowConfigurationException, AuthorizeException, WorkflowException; + + /** + * This method will create the workflowRoleGroup for a collection and the given rolename + * @param context The relevant DSpace context + * @param collection The collection + * @param roleName The rolename + * @return The created Group + * @throws AuthorizeException If something goes wrong + * @throws SQLException If something goes wrong + * @throws IOException If something goes wrong + * @throws WorkflowConfigurationException If something goes wrong + */ + public Group createWorkflowRoleGroup(Context context, Collection collection, String roleName) + throws AuthorizeException, SQLException, IOException, WorkflowConfigurationException; + + public List getFlywayMigrationLocations(); +} diff --git a/dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactory.java b/dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactory.java new file mode 100644 index 0000000000..b338e54f5a --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/workflow/factory/WorkflowServiceFactory.java @@ -0,0 +1,30 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.workflow.factory; + +import org.dspace.services.factory.DSpaceServicesFactory; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.WorkflowService; + +/** + * Abstract factory to get services for the workflow package, use WorkflowServiceFactory.getInstance() to retrieve an + * implementation + * + * @author kevinvandevelde at atmire.com + */ +public abstract class WorkflowServiceFactory { + + public abstract WorkflowService getWorkflowService(); + + public abstract WorkflowItemService getWorkflowItemService(); + + public static WorkflowServiceFactory getInstance() { + return DSpaceServicesFactory.getInstance().getServiceManager() + .getServiceByName("workflowServiceFactory", WorkflowServiceFactory.class); + } +} diff --git a/dspace-api/src/main/java/org/dspace/workflow/package.html b/dspace-api/src/main/java/org/dspace/workflow/package.html new file mode 100644 index 0000000000..1cc217af71 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/workflow/package.html @@ -0,0 +1,41 @@ + + + + + + + +

DSpace's workflow system

+ +

+DSpace has a simple workflow system, which models the workflows +as 5 steps: SUBMIT, three intermediate steps (STEP1, STEP2, STEP3), and ARCHIVE. +When an item is submitted to DSpace, it is in the SUBMIT state. If there +are no intermediate states defined, then it proceeds directly to ARCHIVE and +is put into the main DSpace archive. +

+ +

+EPerson groups may be assigned to the three possible intermediate steps, +where they are expected to act on the item at those steps. For example, +if a Collection's owners desire a review step, they would create a Group +of reviewers, and assign that Group to step 1. The members of step 1's +Group will receive emails asking them to review the submission, and +will need to perform an action on the item before it can be rejected +back to the submitter or placed in the archive. +

+ + + diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactory.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactory.java index 166ef8defd..639a8d3770 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactory.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactory.java @@ -8,6 +8,7 @@ package org.dspace.xmlworkflow.factory; import org.dspace.services.factory.DSpaceServicesFactory; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; @@ -23,7 +24,7 @@ import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; * * @author kevinvandevelde at atmire.com */ -public abstract class XmlWorkflowServiceFactory { +public abstract class XmlWorkflowServiceFactory extends WorkflowServiceFactory { public abstract XmlWorkflowFactory getWorkflowFactory(); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactoryImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactoryImpl.java index 8d8e9fe735..5f36285d86 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/factory/XmlWorkflowServiceFactoryImpl.java @@ -7,6 +7,8 @@ */ package org.dspace.xmlworkflow.factory; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.WorkflowService; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; import org.dspace.xmlworkflow.service.XmlWorkflowService; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; @@ -88,4 +90,14 @@ public class XmlWorkflowServiceFactoryImpl extends XmlWorkflowServiceFactory { public XmlWorkflowItemService getXmlWorkflowItemService() { return xmlWorkflowItemService; } + + @Override + public WorkflowService getWorkflowService() { + return getXmlWorkflowService(); + } + + @Override + public WorkflowItemService getWorkflowItemService() { + return getXmlWorkflowItemService(); + } } diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/migration/RestartWorkflow.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/migration/RestartWorkflow.java index 7b15f020ce..60e520eee0 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/migration/RestartWorkflow.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/migration/RestartWorkflow.java @@ -23,9 +23,9 @@ import org.dspace.core.LogManager; import org.dspace.eperson.EPerson; import org.dspace.eperson.factory.EPersonServiceFactory; import org.dspace.eperson.service.EPersonService; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; -import org.dspace.xmlworkflow.service.XmlWorkflowService; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowService; +import org.dspace.workflow.factory.WorkflowServiceFactory; /** * A utility class that will send all the worklfow items @@ -114,11 +114,11 @@ public class RestartWorkflow { System.out.println("Sending all workflow items back to the workspace"); - XmlWorkflowServiceFactory workflowServiceFactory = XmlWorkflowServiceFactory.getInstance(); - List workflowItems = workflowServiceFactory.getXmlWorkflowItemService().findAll(context); - XmlWorkflowService workflowService = workflowServiceFactory.getXmlWorkflowService(); + WorkflowServiceFactory workflowServiceFactory = WorkflowServiceFactory.getInstance(); + List workflowItems = workflowServiceFactory.getWorkflowItemService().findAll(context); + WorkflowService workflowService = workflowServiceFactory.getWorkflowService(); int i = 0; - for (XmlWorkflowItem workflowItem : workflowItems) { + for (WorkflowItem workflowItem : workflowItems) { System.out.println("Processing workflow item " + i + " of " + workflowItems.size()); System.out.println("Removing pooled tasks"); diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/service/XmlWorkflowService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/service/XmlWorkflowService.java index af8554be8f..f1f72b1b28 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/service/XmlWorkflowService.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/service/XmlWorkflowService.java @@ -14,15 +14,12 @@ import javax.mail.MessagingException; import javax.servlet.http.HttpServletRequest; import org.dspace.authorize.AuthorizeException; -import org.dspace.content.Collection; import org.dspace.content.Item; -import org.dspace.content.WorkspaceItem; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.eperson.Group; import org.dspace.workflow.WorkflowException; +import org.dspace.workflow.WorkflowService; import org.dspace.xmlworkflow.RoleMembers; -import org.dspace.xmlworkflow.WorkflowConfigurationException; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Workflow; import org.dspace.xmlworkflow.state.actions.ActionResult; @@ -33,7 +30,7 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** * When an item is submitted and is somewhere in a workflow, it has a row in the - * cwf_workflowitem table pointing to it. + * WorkflowItem table pointing to it. * * Once the item has completed the workflow it will be archived * @@ -42,101 +39,7 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; * @author Ben Bosman (ben at atmire dot com) * @author Mark Diggory (markd at atmire dot com) */ -public interface XmlWorkflowService { - /** - * startWorkflow() begins a workflow - in a single transaction do away with - * the PersonalWorkspace entry and turn it into a WorkflowItem. - * - * @param context The relevant DSpace Context. - * @param wsi The WorkspaceItem to convert to a workflow item - * @return The resulting workflow item - * @throws SQLException An exception that provides information on a database access error or other errors. - * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. - * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. - * @throws WorkflowException if workflow error - */ - public XmlWorkflowItem start(Context context, WorkspaceItem wsi) - throws SQLException, AuthorizeException, IOException, WorkflowException; - - /** - * startWithoutNotify() starts the workflow normally, but disables - * notifications (useful for large imports,) for the first workflow step - - * subsequent notifications happen normally - * - * @param c The relevant DSpace Context. - * @param wsi workspace item - * @return the resulting workflow item. - * @throws SQLException An exception that provides information on a database access error or other errors. - * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. - * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. - * @throws WorkflowException if workflow error - */ - public XmlWorkflowItem startWithoutNotify(Context c, WorkspaceItem wsi) - throws SQLException, AuthorizeException, IOException, WorkflowException; - - /** - * abort() aborts a workflow, completely deleting it (administrator do this) - * (it will basically do a reject from any state - the item ends up back in - * the user's PersonalWorkspace - * - * @param c The relevant DSpace Context. - * @param wi WorkflowItem to operate on - * @param e EPerson doing the operation - * @return workspace item returned to workspace - * @throws SQLException An exception that provides information on a database access error or other errors. - * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. - * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. - */ - public WorkspaceItem abort(Context c, XmlWorkflowItem wi, EPerson e) - throws SQLException, AuthorizeException, IOException; - - /** - * Deletes workflow task item in correct order. - * - * @param c The relevant DSpace Context. - * @param wi The WorkflowItem that shall be deleted. - * @param e Admin that deletes this workflow task and item (for logging - * @throws SQLException An exception that provides information on a database access error or other errors. - * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. - * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. - */ - public void deleteWorkflowByWorkflowItem(Context c, XmlWorkflowItem wi, EPerson e) - throws SQLException, AuthorizeException, IOException; - - public WorkspaceItem sendWorkflowItemBackSubmission(Context c, XmlWorkflowItem workflowItem, EPerson e, - String provenance, - String rejection_message) - throws SQLException, AuthorizeException, IOException; - - public String getMyDSpaceLink(); - - public void deleteCollection(Context context, Collection collection) - throws SQLException, IOException, AuthorizeException; - - public List getEPersonDeleteConstraints(Context context, EPerson ePerson) throws SQLException; - - public Group getWorkflowRoleGroup(Context context, Collection collection, String roleName, Group roleGroup) - throws SQLException, IOException, WorkflowConfigurationException, AuthorizeException, WorkflowException; - - /** - * This method will create the workflowRoleGroup for a collection and the given rolename - * @param context The relevant DSpace context - * @param collection The collection - * @param roleName The rolename - * @return The created Group - * @throws AuthorizeException If something goes wrong - * @throws SQLException If something goes wrong - * @throws IOException If something goes wrong - * @throws WorkflowConfigurationException If something goes wrong - */ - public Group createWorkflowRoleGroup(Context context, Collection collection, String roleName) - throws AuthorizeException, SQLException, IOException, WorkflowConfigurationException; - - public List getFlywayMigrationLocations(); +public interface XmlWorkflowService extends WorkflowService { public void alertUsersOnTaskActivation(Context c, XmlWorkflowItem wfi, String emailTemplate, List epa, String... arguments) throws IOException, SQLException, MessagingException; diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItem.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItem.java index c845578df6..f6ffe6049a 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItem.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/XmlWorkflowItem.java @@ -20,10 +20,10 @@ import javax.persistence.SequenceGenerator; import javax.persistence.Table; import org.dspace.content.Collection; -import org.dspace.content.InProgressSubmission; import org.dspace.content.Item; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; /** @@ -36,7 +36,7 @@ import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; */ @Entity @Table(name = "cwf_workflowitem") -public class XmlWorkflowItem implements InProgressSubmission { +public class XmlWorkflowItem implements WorkflowItem { @Id @Column(name = "workflowitem_id") diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/XmlWorkflowItemService.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/XmlWorkflowItemService.java index ebb9614a72..76b1fa0817 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/XmlWorkflowItemService.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/service/XmlWorkflowItemService.java @@ -7,16 +7,13 @@ */ package org.dspace.xmlworkflow.storedcomponents.service; -import java.io.IOException; import java.sql.SQLException; import java.util.List; -import org.dspace.authorize.AuthorizeException; import org.dspace.content.Collection; -import org.dspace.content.Item; -import org.dspace.content.service.InProgressSubmissionService; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +import org.dspace.workflow.WorkflowItemService; import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; /** @@ -26,87 +23,7 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; * * @author kevinvandevelde at atmire.com */ -public interface XmlWorkflowItemService extends InProgressSubmissionService { - - public XmlWorkflowItem create(Context context, Item item, Collection collection) throws SQLException, - AuthorizeException; - - /** - * Get a workflow item from the database. - * - * @param context The relevant DSpace Context. - * @param id ID of the workflow item - * @return the workflow item, or null if the ID is invalid. - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - public XmlWorkflowItem find(Context context, int id) throws SQLException; - - /** - * return all workflowitems - * - * @param context The relevant DSpace Context. - * @return List of all workflowItems in system - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - public List findAll(Context context) throws SQLException; - - /** - * Get all workflow items for a particular collection. - * - * @param context The relevant DSpace Context. - * @param collection the collection - * @return array of the corresponding workflow items - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - public List findByCollection(Context context, Collection collection) throws SQLException; - - /** - * Check to see if a particular item is currently under Workflow. - * If so, its WorkflowItem is returned. If not, null is returned - * - * @param context The relevant DSpace Context. - * @param item the item - * @return workflow item corresponding to the item, or null - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - public XmlWorkflowItem findByItem(Context context, Item item) throws SQLException; - - /** - * Get all workflow items that were original submissions by a particular - * e-person. - * - * @param context The relevant DSpace Context. - * @param ep the eperson - * @return the corresponding workflow items - * @throws SQLException An exception that provides information on a database access error or other errors. - */ - public List findBySubmitter(Context context, EPerson ep) throws SQLException; - - /** - * Delete all workflow items present in the specified collection. - * - * @param context The relevant DSpace Context. - * @param collection the containing collection - * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. - * @throws SQLException An exception that provides information on a database access error or other errors. - * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. - */ - public void deleteByCollection(Context context, Collection collection) - throws SQLException, IOException, AuthorizeException; - - /** - * Delete the specified workflow item. - * - * @param context The relevant DSpace Context. - * @param workflowItem which workflow item to delete - * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. - * @throws SQLException An exception that provides information on a database access error or other errors. - * @throws AuthorizeException Exception indicating the current user of the context does not have permission - * to perform a particular action. - */ - public void delete(Context context, XmlWorkflowItem workflowItem) - throws SQLException, AuthorizeException, IOException; +public interface XmlWorkflowItemService extends WorkflowItemService { /** * return all workflowitems for a certain page @@ -153,7 +70,7 @@ public interface XmlWorkflowItemService extends InProgressSubmissionService wfs; @Autowired AuthorizeService authorizeService; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemStepLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemStepLinkRepository.java index 004e0a3541..30aac1579c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemStepLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/WorkflowItemStepLinkRepository.java @@ -47,14 +47,14 @@ public class WorkflowItemStepLinkRepository extends AbstractDSpaceRestRepository private XmlWorkflowFactory xmlWorkflowFactory; /** - * This method will retrieve the {@link WorkflowStepRest} object for the {@link XmlWorkflowItem} + * This method will retrieve the {@link WorkflowStepRest} object for the {@link org.dspace.workflow.WorkflowItem} * with the given id * @param request The current request * @param workflowItemId The id for the WorkflowItem to be used * @param optionalPageable The pageable if relevant * @param projection The Projection * @return The {@link WorkflowStepRest} object related to the - * {@link XmlWorkflowItem} specified by the given ID + * {@link org.dspace.workflow.WorkflowItem} specified by the given ID */ public WorkflowStepRest getStep(@Nullable HttpServletRequest request, Integer workflowItemId, diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/SubmissionService.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/SubmissionService.java index 7da5a3b71a..0ac468448b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/SubmissionService.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/SubmissionService.java @@ -49,9 +49,9 @@ import org.dspace.services.ConfigurationService; import org.dspace.services.RequestService; import org.dspace.services.model.Request; import org.dspace.workflow.WorkflowException; -import org.dspace.xmlworkflow.service.XmlWorkflowService; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.WorkflowService; import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.datasource.init.UncategorizedScriptException; import org.springframework.stereotype.Component; @@ -75,9 +75,9 @@ public class SubmissionService { @Autowired protected WorkspaceItemService workspaceItemService; @Autowired - protected XmlWorkflowItemService workflowItemService; + protected WorkflowItemService workflowItemService; @Autowired - protected XmlWorkflowService workflowService; + protected WorkflowService workflowService; @Autowired protected CreativeCommonsService creativeCommonsService; @Autowired diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionGroupRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionGroupRestControllerIT.java index 19fe98a3a6..767ea5f565 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionGroupRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionGroupRestControllerIT.java @@ -33,7 +33,7 @@ import org.dspace.content.service.CollectionService; import org.dspace.core.Constants; import org.dspace.eperson.Group; import org.dspace.eperson.service.GroupService; -import org.dspace.xmlworkflow.service.XmlWorkflowService; +import org.dspace.workflow.WorkflowService; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -51,7 +51,7 @@ public class CollectionGroupRestControllerIT extends AbstractControllerIntegrati private AuthorizeService authorizeService; @Autowired - private XmlWorkflowService workflowService; + private WorkflowService workflowService; Collection collection; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java index 1f09fe80d0..084c08b231 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java @@ -75,7 +75,7 @@ import org.dspace.eperson.service.AccountService; import org.dspace.eperson.service.EPersonService; import org.dspace.eperson.service.RegistrationDataService; import org.dspace.services.ConfigurationService; -import org.dspace.xmlworkflow.service.XmlWorkflowService; +import org.dspace.workflow.WorkflowService; import org.hamcrest.Matchers; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -93,7 +93,7 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest { private EPersonService ePersonService; @Autowired - private XmlWorkflowService workflowService; + private WorkflowService workflowService; @Autowired private RegistrationDataDAO registrationDataDAO; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/StatisticsRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/StatisticsRestRepositoryIT.java index ef2ac3244e..08303e57f2 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/StatisticsRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/StatisticsRestRepositoryIT.java @@ -995,7 +995,7 @@ public class StatisticsRestRepositoryIT extends AbstractControllerIntegrationTes // ** THEN ** .andExpect(status().isOk()) .andExpect(jsonPath("$._embedded.usagereports", not(empty()))) - .andExpect(jsonPath("$._embedded.usagereports", Matchers.hasItems( + .andExpect(jsonPath("$._embedded.usagereports", Matchers.containsInAnyOrder( UsageReportMatcher .matchUsageReport(collectionNotVisited.getID() + "_" + TOTAL_VISITS_REPORT_ID, TOTAL_VISITS_REPORT_ID, @@ -1007,8 +1007,7 @@ public class StatisticsRestRepositoryIT extends AbstractControllerIntegrationTes UsageReportMatcher.matchUsageReport(collectionNotVisited.getID() + "_" + TOP_CITIES_REPORT_ID, TOP_CITIES_REPORT_ID, new ArrayList<>()), UsageReportMatcher.matchUsageReport(collectionNotVisited.getID() + "_" + TOP_COUNTRIES_REPORT_ID, - TOP_COUNTRIES_REPORT_ID, new ArrayList<>()) - ))); + TOP_COUNTRIES_REPORT_ID, new ArrayList<>())))); } @Test diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ReinstateFeatureRestIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ReinstateFeatureRestIT.java index b36a9c2487..8c630a6795 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ReinstateFeatureRestIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ReinstateFeatureRestIT.java @@ -7,7 +7,6 @@ */ package org.dspace.app.rest.authorization; -import static org.dspace.builder.WorkflowItemBuilder.createWorkflowItem; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.is; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -24,13 +23,14 @@ import org.dspace.app.rest.utils.Utils; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.ItemBuilder; +import org.dspace.builder.WorkflowItemBuilder; import org.dspace.builder.WorkspaceItemBuilder; import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; import org.dspace.services.ConfigurationService; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.workflow.WorkflowItem; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; @@ -239,7 +239,7 @@ public class ReinstateFeatureRestIT extends AbstractControllerIntegrationTest { Item archivedItem = ItemBuilder.createItem(context, col).withTitle("Item already in archive").build(); WorkspaceItem wsItem = WorkspaceItemBuilder.createWorkspaceItem(context, col).withTitle("A workspace item") .build(); - XmlWorkflowItem wfItem = createWorkflowItem(context, col).withTitle("A workflow item").build(); + WorkflowItem wfItem = WorkflowItemBuilder.createWorkflowItem(context, col).withTitle("A workflow item").build(); context.restoreAuthSystemState(); ItemRest archivedItemRest = itemConverter.convert(archivedItem, Projection.DEFAULT); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/WithdrawFeatureRestIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/WithdrawFeatureRestIT.java index df1d8105dd..e0d00fa63a 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/WithdrawFeatureRestIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/WithdrawFeatureRestIT.java @@ -7,7 +7,6 @@ */ package org.dspace.app.rest.authorization; -import static org.dspace.builder.WorkflowItemBuilder.createWorkflowItem; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.is; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -24,13 +23,14 @@ import org.dspace.app.rest.utils.Utils; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.ItemBuilder; +import org.dspace.builder.WorkflowItemBuilder; import org.dspace.builder.WorkspaceItemBuilder; import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; import org.dspace.services.ConfigurationService; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; +import org.dspace.workflow.WorkflowItem; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; @@ -240,7 +240,7 @@ public class WithdrawFeatureRestIT extends AbstractControllerIntegrationTest { .build(); WorkspaceItem wsItem = WorkspaceItemBuilder.createWorkspaceItem(context, col).withTitle("A workspace item") .build(); - XmlWorkflowItem wfItem = createWorkflowItem(context, col).withTitle("A workflow item").build(); + WorkflowItem wfItem = WorkflowItemBuilder.createWorkflowItem(context, col).withTitle("A workflow item").build(); context.restoreAuthSystemState(); ItemRest withdrawnItemRest = itemConverter.convert(withdrawnItem, Projection.DEFAULT); diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java b/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java index cc06e3398d..3beea04d95 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java @@ -24,9 +24,9 @@ import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.WorkspaceItemService; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.swordapp.server.AuthCredentials; import org.swordapp.server.CollectionListManager; import org.swordapp.server.SwordAuthException; @@ -39,8 +39,8 @@ public class CollectionListManagerDSpace extends DSpaceSwordAPI protected WorkspaceItemService workspaceItemService = ContentServiceFactory .getInstance().getWorkspaceItemService(); - protected XmlWorkflowItemService workflowItemService = XmlWorkflowServiceFactory - .getInstance().getXmlWorkflowItemService(); + protected WorkflowItemService workflowItemService = WorkflowServiceFactory + .getInstance().getWorkflowItemService(); @Override public Feed listCollectionContents(IRI colIRI, @@ -144,8 +144,8 @@ public class CollectionListManagerDSpace extends DSpaceSwordAPI List wfis = workflowItemService.findBySubmitter(sc.getContext(), person); for (Object found : wfis) { - if (found instanceof XmlWorkflowItem) { - XmlWorkflowItem wfi = (XmlWorkflowItem) found; + if (found instanceof WorkflowItem) { + WorkflowItem wfi = (WorkflowItem) found; Item item = wfi.getItem(); // check for the wfi collection diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/ContainerManagerDSpace.java b/dspace-swordv2/src/main/java/org/dspace/sword2/ContainerManagerDSpace.java index 35991e1a32..9bb6eb8790 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/ContainerManagerDSpace.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/ContainerManagerDSpace.java @@ -25,9 +25,9 @@ import org.dspace.content.service.WorkspaceItemService; import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.core.LogManager; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.factory.WorkflowServiceFactory; import org.swordapp.server.AuthCredentials; import org.swordapp.server.ContainerManager; import org.swordapp.server.Deposit; @@ -44,8 +44,8 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI protected AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService(); - protected XmlWorkflowItemService workflowItemService = - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService(); + protected WorkflowItemService workflowItemService = + WorkflowServiceFactory.getInstance().getWorkflowItemService(); protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); @@ -757,7 +757,7 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI WorkspaceItem wsi = wft.getWorkspaceItem(context, item); workspaceItemService.deleteAll(context, wsi); } else if (wft.isItemInWorkflow(context, item)) { - XmlWorkflowItem wfi = wft.getWorkflowItem(context, item); + WorkflowItem wfi = wft.getWorkflowItem(context, item); workflowItemService.deleteWrapper(context, wfi); } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowTools.java b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowTools.java index 30bcfd4111..bb20866447 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowTools.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowTools.java @@ -19,20 +19,20 @@ import org.dspace.core.Context; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.workflow.WorkflowException; -import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; -import org.dspace.xmlworkflow.service.XmlWorkflowService; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; -import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; +import org.dspace.workflow.WorkflowItem; +import org.dspace.workflow.WorkflowItemService; +import org.dspace.workflow.WorkflowService; +import org.dspace.workflow.factory.WorkflowServiceFactory; public class WorkflowTools { protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); - protected XmlWorkflowItemService workflowItemService = - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService(); + protected WorkflowItemService workflowItemService = + WorkflowServiceFactory.getInstance().getWorkflowItemService(); - protected XmlWorkflowService workflowService = - XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService(); + protected WorkflowService workflowService = + WorkflowServiceFactory.getInstance().getWorkflowService(); protected ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); @@ -88,7 +88,7 @@ public class WorkflowTools { * @return workflow item * @throws DSpaceSwordException can be thrown by the internals of the DSpace SWORD implementation */ - public XmlWorkflowItem getWorkflowItem(Context context, Item item) + public WorkflowItem getWorkflowItem(Context context, Item item) throws DSpaceSwordException { try { return workflowItemService.findByItem(context, item); @@ -154,7 +154,7 @@ public class WorkflowTools { throws DSpaceSwordException { try { // find the item in the workflow if it exists - XmlWorkflowItem wfi = this.getWorkflowItem(context, item); + WorkflowItem wfi = this.getWorkflowItem(context, item); // abort the workflow if (wfi != null) { From 28567c8daa3dde639f9cc08c12c14e5131d9e480 Mon Sep 17 00:00:00 2001 From: Peter Nijs Date: Thu, 25 Feb 2021 12:16:02 +0100 Subject: [PATCH 085/179] 77250: Revert code style changes --- .../dspace/app/rest/ItemRestRepositoryIT.java | 558 +++++++++--------- 1 file changed, 267 insertions(+), 291 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java index 233cc4e7db..b4b84cee38 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java @@ -2931,12 +2931,12 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context) - .withName("Parent Community") - .build(); + .withName("Parent Community") + .build(); Collection collection = CollectionBuilder.createCollection(context, parentCommunity) - .withName("Collection") - .build(); + .withName("Collection") + .build(); Item item = ItemBuilder.createItem(context, collection).withTitle("Item").build(); @@ -2954,34 +2954,24 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); getClient().perform(get("/api/core/items/" + item.getID()) - .param("embed", "bundles")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) - .andExpect(jsonPath("$._embedded.bundles._embedded.bundles",Matchers.containsInAnyOrder( - BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), - bundle0.getType()), - BundleMatcher.matchProperties(bundle1.getName(), bundle1.getID(), bundle1.getHandle(), - bundle1.getType()), - BundleMatcher.matchProperties(bundle2.getName(), bundle2.getID(), bundle2.getHandle(), - bundle2.getType()), - BundleMatcher.matchProperties(bundle3.getName(), bundle3.getID(), bundle3.getHandle(), - bundle3.getType()), - BundleMatcher.matchProperties(bundle4.getName(), bundle4.getID(), bundle4.getHandle(), - bundle4.getType()), - BundleMatcher.matchProperties(bundle5.getName(), bundle5.getID(), bundle5.getHandle(), - bundle5.getType()), - BundleMatcher.matchProperties(bundle6.getName(), bundle6.getID(), bundle6.getHandle(), - bundle6.getType()), - BundleMatcher.matchProperties(bundle7.getName(), bundle7.getID(), bundle7.getHandle(), - bundle7.getType()), - BundleMatcher.matchProperties(bundle8.getName(), bundle8.getID(), bundle8.getHandle(), - bundle8.getType()), - BundleMatcher.matchProperties(bundle9.getName(), bundle9.getID(), bundle9.getHandle(), - bundle9.getType()) - ))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items/" + item.getID()))) - .andExpect(jsonPath("$._embedded.bundles.page.size", is(20))) - .andExpect(jsonPath("$._embedded.bundles.page.totalElements", is(10))); + .param("embed", "bundles")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$._embedded.bundles._embedded.bundles",Matchers.containsInAnyOrder( + BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), bundle0.getType()), + BundleMatcher.matchProperties(bundle1.getName(), bundle1.getID(), bundle1.getHandle(), bundle1.getType()), + BundleMatcher.matchProperties(bundle2.getName(), bundle2.getID(), bundle2.getHandle(), bundle2.getType()), + BundleMatcher.matchProperties(bundle3.getName(), bundle3.getID(), bundle3.getHandle(), bundle3.getType()), + BundleMatcher.matchProperties(bundle4.getName(), bundle4.getID(), bundle4.getHandle(), bundle4.getType()), + BundleMatcher.matchProperties(bundle5.getName(), bundle5.getID(), bundle5.getHandle(), bundle5.getType()), + BundleMatcher.matchProperties(bundle6.getName(), bundle6.getID(), bundle6.getHandle(), bundle6.getType()), + BundleMatcher.matchProperties(bundle7.getName(), bundle7.getID(), bundle7.getHandle(), bundle7.getType()), + BundleMatcher.matchProperties(bundle8.getName(), bundle8.getID(), bundle8.getHandle(), bundle8.getType()), + BundleMatcher.matchProperties(bundle9.getName(), bundle9.getID(), bundle9.getHandle(), bundle9.getType()) + ))) + .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items/" + item.getID()))) + .andExpect(jsonPath("$._embedded.bundles.page.size", is(20))) + .andExpect(jsonPath("$._embedded.bundles.page.totalElements", is(10))); } @Test @@ -2989,12 +2979,12 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context) - .withName("Parent Community") - .build(); + .withName("Parent Community") + .build(); Collection collection = CollectionBuilder.createCollection(context, parentCommunity) - .withName("Collection") - .build(); + .withName("Collection") + .build(); Item item = ItemBuilder.createItem(context, collection).withTitle("Item").build(); @@ -3012,25 +3002,20 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); getClient().perform(get("/api/core/items/" + item.getID()) - .param("embed", "bundles") - .param("embed.size", "bundles=5")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) - .andExpect(jsonPath("$._embedded.bundles._embedded.bundles",Matchers.containsInAnyOrder( - BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), - bundle0.getType()), - BundleMatcher.matchProperties(bundle1.getName(), bundle1.getID(), bundle1.getHandle(), - bundle1.getType()), - BundleMatcher.matchProperties(bundle2.getName(), bundle2.getID(), bundle2.getHandle(), - bundle2.getType()), - BundleMatcher.matchProperties(bundle3.getName(), bundle3.getID(), bundle3.getHandle(), - bundle3.getType()), - BundleMatcher.matchProperties(bundle4.getName(), bundle4.getID(), bundle4.getHandle(), - bundle4.getType()) - ))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items/" + item.getID()))) - .andExpect(jsonPath("$._embedded.bundles.page.size", is(5))) - .andExpect(jsonPath("$._embedded.bundles.page.totalElements", is(10))); + .param("embed", "bundles") + .param("embed.size", "bundles=5")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$._embedded.bundles._embedded.bundles",Matchers.containsInAnyOrder( + BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), bundle0.getType()), + BundleMatcher.matchProperties(bundle1.getName(), bundle1.getID(), bundle1.getHandle(), bundle1.getType()), + BundleMatcher.matchProperties(bundle2.getName(), bundle2.getID(), bundle2.getHandle(), bundle2.getType()), + BundleMatcher.matchProperties(bundle3.getName(), bundle3.getID(), bundle3.getHandle(), bundle3.getType()), + BundleMatcher.matchProperties(bundle4.getName(), bundle4.getID(), bundle4.getHandle(), bundle4.getType()) + ))) + .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items/" + item.getID()))) + .andExpect(jsonPath("$._embedded.bundles.page.size", is(5))) + .andExpect(jsonPath("$._embedded.bundles.page.totalElements", is(10))); } @@ -3039,12 +3024,12 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context) - .withName("Parent Community") - .build(); + .withName("Parent Community") + .build(); Collection collection = CollectionBuilder.createCollection(context, parentCommunity) - .withName("Collection") - .build(); + .withName("Collection") + .build(); Item item = ItemBuilder.createItem(context, collection).withTitle("Item").build(); @@ -3062,48 +3047,38 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); getClient().perform(get("/api/core/items/" + item.getID()) - .param("embed", "bundles") - .param("embed.size", "bundles=invalidPage")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) - .andExpect(jsonPath("$._embedded.bundles._embedded.bundles",Matchers.containsInAnyOrder( - BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), - bundle0.getType()), - BundleMatcher.matchProperties(bundle1.getName(), bundle1.getID(), bundle1.getHandle(), - bundle1.getType()), - BundleMatcher.matchProperties(bundle2.getName(), bundle2.getID(), bundle2.getHandle(), - bundle2.getType()), - BundleMatcher.matchProperties(bundle3.getName(), bundle3.getID(), bundle3.getHandle(), - bundle3.getType()), - BundleMatcher.matchProperties(bundle4.getName(), bundle4.getID(), bundle4.getHandle(), - bundle4.getType()), - BundleMatcher.matchProperties(bundle5.getName(), bundle5.getID(), bundle5.getHandle(), - bundle5.getType()), - BundleMatcher.matchProperties(bundle6.getName(), bundle6.getID(), bundle6.getHandle(), - bundle6.getType()), - BundleMatcher.matchProperties(bundle7.getName(), bundle7.getID(), bundle7.getHandle(), - bundle7.getType()), - BundleMatcher.matchProperties(bundle8.getName(), bundle8.getID(), bundle8.getHandle(), - bundle8.getType()), - BundleMatcher.matchProperties(bundle9.getName(), bundle9.getID(), bundle9.getHandle(), - bundle9.getType()) - ))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items/" + item.getID()))) - .andExpect(jsonPath("$._embedded.bundles.page.size", is(20))) - .andExpect(jsonPath("$._embedded.bundles.page.totalElements", is(10))); - } + .param("embed", "bundles") + .param("embed.size", "bundles=invalidPage")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$._embedded.bundles._embedded.bundles",Matchers.containsInAnyOrder( + BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), bundle0.getType()), + BundleMatcher.matchProperties(bundle1.getName(), bundle1.getID(), bundle1.getHandle(), bundle1.getType()), + BundleMatcher.matchProperties(bundle2.getName(), bundle2.getID(), bundle2.getHandle(), bundle2.getType()), + BundleMatcher.matchProperties(bundle3.getName(), bundle3.getID(), bundle3.getHandle(), bundle3.getType()), + BundleMatcher.matchProperties(bundle4.getName(), bundle4.getID(), bundle4.getHandle(), bundle4.getType()), + BundleMatcher.matchProperties(bundle5.getName(), bundle5.getID(), bundle5.getHandle(), bundle5.getType()), + BundleMatcher.matchProperties(bundle6.getName(), bundle6.getID(), bundle6.getHandle(), bundle6.getType()), + BundleMatcher.matchProperties(bundle7.getName(), bundle7.getID(), bundle7.getHandle(), bundle7.getType()), + BundleMatcher.matchProperties(bundle8.getName(), bundle8.getID(), bundle8.getHandle(), bundle8.getType()), + BundleMatcher.matchProperties(bundle9.getName(), bundle9.getID(), bundle9.getHandle(), bundle9.getType()) + ))) + .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items/" + item.getID()))) + .andExpect(jsonPath("$._embedded.bundles.page.size", is(20))) + .andExpect(jsonPath("$._embedded.bundles.page.totalElements", is(10))); +} @Test public void findOneTestWithMultiLevelEmbedsWithNoPageSize() throws Exception { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context) - .withName("Parent Community") - .build(); + .withName("Parent Community") + .build(); Collection collection = CollectionBuilder.createCollection(context, parentCommunity) - .withName("Collection") - .build(); + .withName("Collection") + .build(); Item item = ItemBuilder.createItem(context, collection).withTitle("Item").build(); @@ -3114,104 +3089,104 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { Bitstream bitstream0; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream0 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream0") - .withMimeType("text/plain") - .build(); + .withName("Bitstream0") + .withMimeType("text/plain") + .build(); } Bitstream bitstream1; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream1 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream1") - .withMimeType("text/plain") - .build(); + .withName("Bitstream1") + .withMimeType("text/plain") + .build(); } Bitstream bitstream2; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream2 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream2") - .withMimeType("text/plain") - .build(); + .withName("Bitstream2") + .withMimeType("text/plain") + .build(); } Bitstream bitstream3; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream3 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream3") - .withMimeType("text/plain") - .build(); + .withName("Bitstream3") + .withMimeType("text/plain") + .build(); } Bitstream bitstream4; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream4 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream4") - .withMimeType("text/plain") - .build(); + .withName("Bitstream4") + .withMimeType("text/plain") + .build(); } Bitstream bitstream5; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream5 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream5") - .withMimeType("text/plain") - .build(); + .withName("Bitstream5") + .withMimeType("text/plain") + .build(); } Bitstream bitstream6; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream6 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream6") - .withMimeType("text/plain") - .build(); + .withName("Bitstream6") + .withMimeType("text/plain") + .build(); } Bitstream bitstream7; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream7 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream7") - .withMimeType("text/plain") - .build(); + .withName("Bitstream7") + .withMimeType("text/plain") + .build(); } Bitstream bitstream8; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream8 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream8") - .withMimeType("text/plain") - .build(); + .withName("Bitstream8") + .withMimeType("text/plain") + .build(); } Bitstream bitstream9; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream9 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream9") - .withMimeType("text/plain") - .build(); + .withName("Bitstream9") + .withMimeType("text/plain") + .build(); } context.restoreAuthSystemState(); getClient().perform(get("/api/core/items/" + item.getID()) - .param("embed", "bundles/bitstreams")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) - .andExpect(jsonPath("$._embedded.bundles._embedded.bundles", Matchers.containsInAnyOrder( - BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), - bundle0.getType()) - ))) - .andExpect(jsonPath("$._embedded.bundles._embedded.bundles[0]._embedded.bitstreams" + - "._embedded.bitstreams", - Matchers.containsInAnyOrder( - BitstreamMatcher.matchProperties(bitstream0), - BitstreamMatcher.matchProperties(bitstream1), - BitstreamMatcher.matchProperties(bitstream2), - BitstreamMatcher.matchProperties(bitstream3), - BitstreamMatcher.matchProperties(bitstream4), - BitstreamMatcher.matchProperties(bitstream5), - BitstreamMatcher.matchProperties(bitstream6), - BitstreamMatcher.matchProperties(bitstream7), - BitstreamMatcher.matchProperties(bitstream8), - BitstreamMatcher.matchProperties(bitstream9) - ))) - .andExpect( - jsonPath("$._links.self.href", Matchers.containsString("/api/core/items/" + item.getID()))) - .andExpect(jsonPath("$._embedded.bundles._embedded.bundles[0]." + - "_embedded.bitstreams.page.size", is(20))) - .andExpect(jsonPath("$._embedded.bundles._embedded.bundles[0]" + - "._embedded.bitstreams.page.totalElements", - is(10))); + .param("embed", "bundles/bitstreams")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$._embedded.bundles._embedded.bundles", Matchers.containsInAnyOrder( + BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), + bundle0.getType()) + ))) + .andExpect(jsonPath("$._embedded.bundles._embedded.bundles[0]._embedded.bitstreams" + + "._embedded.bitstreams", + Matchers.containsInAnyOrder( + BitstreamMatcher.matchProperties(bitstream0), + BitstreamMatcher.matchProperties(bitstream1), + BitstreamMatcher.matchProperties(bitstream2), + BitstreamMatcher.matchProperties(bitstream3), + BitstreamMatcher.matchProperties(bitstream4), + BitstreamMatcher.matchProperties(bitstream5), + BitstreamMatcher.matchProperties(bitstream6), + BitstreamMatcher.matchProperties(bitstream7), + BitstreamMatcher.matchProperties(bitstream8), + BitstreamMatcher.matchProperties(bitstream9) + ))) + .andExpect( + jsonPath("$._links.self.href", Matchers.containsString("/api/core/items/" + item.getID()))) + .andExpect(jsonPath("$._embedded.bundles._embedded.bundles[0]." + + "_embedded.bitstreams.page.size", is(20))) + .andExpect(jsonPath("$._embedded.bundles._embedded.bundles[0]" + + "._embedded.bitstreams.page.totalElements", + is(10))); } @Test @@ -3219,12 +3194,12 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context) - .withName("Parent Community") - .build(); + .withName("Parent Community") + .build(); Collection collection = CollectionBuilder.createCollection(context, parentCommunity) - .withName("Collection") - .build(); + .withName("Collection") + .build(); Item item = ItemBuilder.createItem(context, collection).withTitle("Item").build(); @@ -3235,100 +3210,100 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { Bitstream bitstream0; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream0 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream0") - .withMimeType("text/plain") - .build(); + .withName("Bitstream0") + .withMimeType("text/plain") + .build(); } Bitstream bitstream1; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream1 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream1") - .withMimeType("text/plain") - .build(); + .withName("Bitstream1") + .withMimeType("text/plain") + .build(); } Bitstream bitstream2; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream2 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream2") - .withMimeType("text/plain") - .build(); + .withName("Bitstream2") + .withMimeType("text/plain") + .build(); } Bitstream bitstream3; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream3 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream3") - .withMimeType("text/plain") - .build(); + .withName("Bitstream3") + .withMimeType("text/plain") + .build(); } Bitstream bitstream4; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream4 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream4") - .withMimeType("text/plain") - .build(); + .withName("Bitstream4") + .withMimeType("text/plain") + .build(); } Bitstream bitstream5; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream5 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream5") - .withMimeType("text/plain") - .build(); + .withName("Bitstream5") + .withMimeType("text/plain") + .build(); } Bitstream bitstream6; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream6 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream6") - .withMimeType("text/plain") - .build(); + .withName("Bitstream6") + .withMimeType("text/plain") + .build(); } Bitstream bitstream7; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream7 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream7") - .withMimeType("text/plain") - .build(); + .withName("Bitstream7") + .withMimeType("text/plain") + .build(); } Bitstream bitstream8; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream8 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream8") - .withMimeType("text/plain") - .build(); + .withName("Bitstream8") + .withMimeType("text/plain") + .build(); } Bitstream bitstream9; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { bitstream9 = BitstreamBuilder.createBitstream(context, bundle0, is) - .withName("Bitstream9") - .withMimeType("text/plain") - .build(); + .withName("Bitstream9") + .withMimeType("text/plain") + .build(); } context.restoreAuthSystemState(); getClient().perform(get("/api/core/items/" + item.getID()) - .param("embed", "bundles/bitstreams") - .param("embed.size", "bundles/bitstreams=5")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) - .andExpect(jsonPath("$._embedded.bundles._embedded.bundles", Matchers.containsInAnyOrder( - BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), - bundle0.getType()) - ))) - .andExpect(jsonPath("$._embedded.bundles._embedded.bundles[0]._embedded.bitstreams" + - "._embedded.bitstreams", - Matchers.containsInAnyOrder( - BitstreamMatcher.matchProperties(bitstream0), - BitstreamMatcher.matchProperties(bitstream1), - BitstreamMatcher.matchProperties(bitstream2), - BitstreamMatcher.matchProperties(bitstream3), - BitstreamMatcher.matchProperties(bitstream4) - ))) - .andExpect( - jsonPath("$._links.self.href", Matchers.containsString("/api/core/items/" + item.getID()))) - .andExpect(jsonPath("$._embedded.bundles._embedded.bundles[0]" + - "._embedded.bitstreams.page.size", is(5))) - .andExpect(jsonPath("$._embedded.bundles._embedded.bundles[0]" + - "._embedded.bitstreams.page.totalElements", - is(10))); + .param("embed", "bundles/bitstreams") + .param("embed.size", "bundles/bitstreams=5")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$._embedded.bundles._embedded.bundles", Matchers.containsInAnyOrder( + BundleMatcher.matchProperties(bundle0.getName(), bundle0.getID(), bundle0.getHandle(), + bundle0.getType()) + ))) + .andExpect(jsonPath("$._embedded.bundles._embedded.bundles[0]._embedded.bitstreams" + + "._embedded.bitstreams", + Matchers.containsInAnyOrder( + BitstreamMatcher.matchProperties(bitstream0), + BitstreamMatcher.matchProperties(bitstream1), + BitstreamMatcher.matchProperties(bitstream2), + BitstreamMatcher.matchProperties(bitstream3), + BitstreamMatcher.matchProperties(bitstream4) + ))) + .andExpect( + jsonPath("$._links.self.href", Matchers.containsString("/api/core/items/" + item.getID()))) + .andExpect(jsonPath("$._embedded.bundles._embedded.bundles[0]" + + "._embedded.bitstreams.page.size", is(5))) + .andExpect(jsonPath("$._embedded.bundles._embedded.bundles[0]" + + "._embedded.bitstreams.page.totalElements", + is(10))); } @Test @@ -3338,26 +3313,26 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { String token = getAuthToken(admin.getEmail(), password); getClient(token).perform(get("/api/core/relationships/" + relationship1.getID())) - .andExpect(status().is(200)); + .andExpect(status().is(200)); getClient(token).perform(delete("/api/core/relationships/" + relationship1.getID())) - .andExpect(status().is(400)); + .andExpect(status().is(400)); //Both relationships still exist getClient(token).perform(get("/api/core/relationships/" + relationship1.getID())) - .andExpect(status().is(200)); + .andExpect(status().is(200)); getClient(token).perform(get("/api/core/relationships/" + relationship2.getID())) - .andExpect(status().is(200)); + .andExpect(status().is(200)); //Delete public item getClient(token).perform(delete("/api/core/items/" + publication1.getID())) - .andExpect(status().is(204)); + .andExpect(status().is(204)); //The item has been deleted getClient(token).perform(get("/api/core/items/" + publication1.getID())) - .andExpect(status().is(404)); + .andExpect(status().is(404)); //The relationships have been deleted getClient(token).perform(get("/api/core/relationships/" + relationship1.getID())) - .andExpect(status().is(404)); + .andExpect(status().is(404)); getClient(token).perform(get("/api/core/relationships/" + relationship2.getID())) - .andExpect(status().is(404)); + .andExpect(status().is(404)); } @@ -3368,15 +3343,15 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { //Delete public item with copyVirtualMetadata null getClient(token).perform(delete("/api/core/items/" + publication1.getID())) - .andExpect(status().is(204)); + .andExpect(status().is(204)); // The non-deleted item of the relationships the delete item had (other sides) doesn't still have the // relationship Metadata getClient(token).perform(get("/api/core/items/" + author1.getID())) - .andExpect(status().is(200)) - .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']").doesNotExist()); + .andExpect(status().is(200)) + .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']").doesNotExist()); getClient(token).perform(get("/api/core/items/" + author2.getID())) - .andExpect(status().is(200)) - .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']").doesNotExist()); + .andExpect(status().is(200)) + .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']").doesNotExist()); } @Test @@ -3389,17 +3364,17 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { getClient(token).perform(delete("/api/core/items/" + publication1.getID()) .param(ItemRestRepository.REQUESTPARAMETER_COPYVIRTUALMETADATA, String.valueOf(isAuthorOfPublication.getID()))) - .andExpect(status().is(204)); + .andExpect(status().is(204)); // The non-deleted item of the relationships the delete item had (other sides) still has the // relationship Metadata getClient(token).perform(get("/api/core/items/" + author1.getID())) - .andExpect(status().is(200)) - .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']" + - "[0].value", is(String.valueOf(publication1.getID())))); + .andExpect(status().is(200)) + .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']" + + "[0].value", is(String.valueOf(publication1.getID())))); getClient(token).perform(get("/api/core/items/" + author2.getID())) - .andExpect(status().is(200)) - .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']" + - "[0].value", is(String.valueOf(publication1.getID())))); + .andExpect(status().is(200)) + .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']" + + "[0].value", is(String.valueOf(publication1.getID())))); } @Test @@ -3422,15 +3397,15 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { getClient(token).perform(delete("/api/core/items/" + publication1.getID()) .param(ItemRestRepository.REQUESTPARAMETER_COPYVIRTUALMETADATA, String.valueOf(isJournalVolumeOfIssueRelationshipType.getID()))) - .andExpect(status().is(204)); + .andExpect(status().is(204)); // The non-deleted item of the relationships the delete item had (other sides) doesn't still have the // relationship Metadata getClient(token).perform(get("/api/core/items/" + author1.getID())) - .andExpect(status().is(200)) - .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']").doesNotExist()); + .andExpect(status().is(200)) + .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']").doesNotExist()); getClient(token).perform(get("/api/core/items/" + author2.getID())) - .andExpect(status().is(200)) - .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']").doesNotExist()); + .andExpect(status().is(200)) + .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']").doesNotExist()); } @Test @@ -3441,17 +3416,17 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { //Delete public item with copyVirtualMetadata = all getClient(token).perform(delete("/api/core/items/" + publication1.getID()) .param(ItemRestRepository.REQUESTPARAMETER_COPYVIRTUALMETADATA, ItemRestRepository.COPYVIRTUAL_ALL)) - .andExpect(status().is(204)); + .andExpect(status().is(204)); // The non-deleted item of the relationships the delete item had (other sides) now still has the // relationship Metadata getClient(token).perform(get("/api/core/items/" + author1.getID())) - .andExpect(status().is(200)) - .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']" + - "[0].value", is(String.valueOf(publication1.getID())))); + .andExpect(status().is(200)) + .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']" + + "[0].value", is(String.valueOf(publication1.getID())))); getClient(token).perform(get("/api/core/items/" + author2.getID())) - .andExpect(status().is(200)) - .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']" + - "[0].value", is(String.valueOf(publication1.getID())))); + .andExpect(status().is(200)) + .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']" + + "[0].value", is(String.valueOf(publication1.getID())))); } @Test @@ -3463,17 +3438,17 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { //Delete public item with copyVirtualMetadata = configured getClient(token).perform(delete("/api/core/items/" + publication1.getID()) .param(ItemRestRepository.REQUESTPARAMETER_COPYVIRTUALMETADATA, ItemRestRepository.COPYVIRTUAL_CONFIGURED)) - .andExpect(status().is(204)); + .andExpect(status().is(204)); // The non-deleted item of the relationships the delete item had (other sides) now still has the // relationship Metadata getClient(token).perform(get("/api/core/items/" + author1.getID())) - .andExpect(status().is(200)) - .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']" + - "[0].value", is(String.valueOf(publication1.getID())))); + .andExpect(status().is(200)) + .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']" + + "[0].value", is(String.valueOf(publication1.getID())))); getClient(token).perform(get("/api/core/items/" + author2.getID())) - .andExpect(status().is(200)) - .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']" + - "[0].value", is(String.valueOf(publication1.getID())))); + .andExpect(status().is(200)) + .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']" + + "[0].value", is(String.valueOf(publication1.getID())))); } @Test @@ -3484,33 +3459,33 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { //** GIVEN ** //1. A community with one collection. parentCommunity = CommunityBuilder.createCommunity(context) - .withName("Parent Community") - .build(); + .withName("Parent Community") + .build(); Collection col1 = CollectionBuilder .createCollection(context, parentCommunity).withName("Collection 1").build(); author1 = ItemBuilder.createItem(context, col1) - .withTitle("Author1") - .withIssueDate("2017-10-17") - .withAuthor("Smith, Donald") - .withPersonIdentifierLastName("Smith") - .withPersonIdentifierFirstName("Donald") - .withRelationshipType("Person") - .build(); + .withTitle("Author1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withPersonIdentifierLastName("Smith") + .withPersonIdentifierFirstName("Donald") + .withRelationshipType("Person") + .build(); author2 = ItemBuilder.createItem(context, col1) - .withTitle("Author2") - .withIssueDate("2016-02-13") - .withAuthor("Smith, Maria") - .withRelationshipType("Person") - .build(); + .withTitle("Author2") + .withIssueDate("2016-02-13") + .withAuthor("Smith, Maria") + .withRelationshipType("Person") + .build(); publication1 = ItemBuilder.createItem(context, col1) - .withTitle("Publication1") - .withAuthor("Testy, TEst") - .withIssueDate("2015-01-01") - .withRelationshipType("Publication") - .build(); + .withTitle("Publication1") + .withAuthor("Testy, TEst") + .withIssueDate("2015-01-01") + .withRelationshipType("Publication") + .build(); EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); EntityType person = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); @@ -3531,15 +3506,15 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { //Delete public item with copyVirtualMetadata = configured getClient(token).perform(delete("/api/core/items/" + publication1.getID()) .param(ItemRestRepository.REQUESTPARAMETER_COPYVIRTUALMETADATA, ItemRestRepository.COPYVIRTUAL_CONFIGURED)) - .andExpect(status().is(204)); + .andExpect(status().is(204)); // The non-deleted item of the relationships the delete item had (other sides) now still has the // relationship Metadata getClient(token).perform(get("/api/core/items/" + author1.getID())) - .andExpect(status().is(200)) - .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']").doesNotExist()); + .andExpect(status().is(200)) + .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']").doesNotExist()); getClient(token).perform(get("/api/core/items/" + author2.getID())) - .andExpect(status().is(200)) - .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']").doesNotExist()); + .andExpect(status().is(200)) + .andExpect(jsonPath("$.metadata['relation.isPublicationOfAuthor']").doesNotExist()); } private void initPublicationAuthorsRelationships() throws SQLException { @@ -3548,33 +3523,33 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { //** GIVEN ** //1. A community with one collection. parentCommunity = CommunityBuilder.createCommunity(context) - .withName("Parent Community") - .build(); + .withName("Parent Community") + .build(); Collection col1 = CollectionBuilder .createCollection(context, parentCommunity).withName("Collection 1").build(); author1 = ItemBuilder.createItem(context, col1) - .withTitle("Author1") - .withIssueDate("2017-10-17") - .withAuthor("Smith, Donald") - .withPersonIdentifierLastName("Smith") - .withPersonIdentifierFirstName("Donald") - .withRelationshipType("Person") - .build(); + .withTitle("Author1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withPersonIdentifierLastName("Smith") + .withPersonIdentifierFirstName("Donald") + .withRelationshipType("Person") + .build(); author2 = ItemBuilder.createItem(context, col1) - .withTitle("Author2") - .withIssueDate("2016-02-13") - .withAuthor("Smith, Maria") - .withRelationshipType("Person") - .build(); + .withTitle("Author2") + .withIssueDate("2016-02-13") + .withAuthor("Smith, Maria") + .withRelationshipType("Person") + .build(); publication1 = ItemBuilder.createItem(context, col1) - .withTitle("Publication1") - .withAuthor("Testy, TEst") - .withIssueDate("2015-01-01") - .withRelationshipType("Publication") - .build(); + .withTitle("Publication1") + .withAuthor("Testy, TEst") + .withIssueDate("2015-01-01") + .withRelationshipType("Publication") + .build(); EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); EntityType person = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); @@ -3591,4 +3566,5 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); } + } From 635d3414695191f559a10c5276d7f09d10aa616f Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 21 Oct 2020 14:07:10 -0500 Subject: [PATCH 086/179] Upgrade to latest guava. Remove/replace outdated Lyncode builders & test-support which used old guava version. --- dspace-oai/pom.xml | 39 +++---------------- .../DSpaceAtLeastOneMetadataFilter.java | 12 +++--- .../dspace/xoai/filter/DateFromFilter.java | 8 +++- .../dspace/xoai/filter/DateUntilFilter.java | 8 +++- .../services/impl/DSpaceServiceResolver.java | 8 ++-- .../impl/xoai/DSpaceItemSolrRepository.java | 12 +++--- .../tests/integration/xoai/PipelineTest.java | 14 ++++++- .../impl/AbstractQueryResolverTest.java | 15 +++++-- dspace/pom.xml | 26 ------------- pom.xml | 7 +--- 10 files changed, 59 insertions(+), 90 deletions(-) diff --git a/dspace-oai/pom.xml b/dspace-oai/pom.xml index 1d9557ed4d..1e71652cc7 100644 --- a/dspace-oai/pom.xml +++ b/dspace-oai/pom.xml @@ -108,6 +108,11 @@ org.dom4j dom4j + + + com.lyncode + test-support + @@ -197,24 +202,6 @@ runtime - - - com.google.guava - guava - 19.0 - - - com.lyncode - builder-commons - 1.0.2 - - - com.google.guava - guava - - - - junit @@ -233,22 +220,6 @@ mockito-core test - - com.lyncode - test-support - 1.0.3 - test - - - com.lyncode - builder-commons - - - com.google.guava - guava - - - org.springframework spring-test diff --git a/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceAtLeastOneMetadataFilter.java b/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceAtLeastOneMetadataFilter.java index 63ff355650..8dc6b771f4 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceAtLeastOneMetadataFilter.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/filter/DSpaceAtLeastOneMetadataFilter.java @@ -8,11 +8,13 @@ package org.dspace.xoai.filter; +import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Lists.transform; + import java.util.ArrayList; import java.util.List; import com.google.common.base.Function; -import com.lyncode.builder.ListBuilder; import com.lyncode.xoai.dataprovider.xml.xoaiconfig.parameters.ParameterList; import com.lyncode.xoai.dataprovider.xml.xoaiconfig.parameters.ParameterValue; import com.lyncode.xoai.dataprovider.xml.xoaiconfig.parameters.SimpleType; @@ -52,14 +54,14 @@ public class DSpaceAtLeastOneMetadataFilter extends DSpaceFilter { values = new ArrayList<>(); values.add(((SimpleType) parameterValue).asString()); } else if (parameterValue instanceof ParameterList) { - values = new ListBuilder() - .add(parameterValue.asParameterList().getValues()) - .build(new Function() { + // transform list of ParameterValues into list of Strings + values = newArrayList(transform(parameterValue.asParameterList().getValues(), + new Function() { @Override public String apply(ParameterValue elem) { return elem.asSimpleType().asString(); } - }); + })); } else { values = new ArrayList<>(); } diff --git a/dspace-oai/src/main/java/org/dspace/xoai/filter/DateFromFilter.java b/dspace-oai/src/main/java/org/dspace/xoai/filter/DateFromFilter.java index 57716d12ea..a0ac4c2676 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/filter/DateFromFilter.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/filter/DateFromFilter.java @@ -7,9 +7,9 @@ */ package org.dspace.xoai.filter; +import java.util.Calendar; import java.util.Date; -import com.lyncode.builder.DateBuilder; import com.lyncode.xoai.dataprovider.services.api.DateProvider; import com.lyncode.xoai.dataprovider.services.impl.BaseDateProvider; import org.apache.solr.client.solrj.util.ClientUtils; @@ -24,7 +24,11 @@ public class DateFromFilter extends DSpaceFilter { private final Date date; public DateFromFilter(Date date) { - this.date = new DateBuilder(date).setMinMilliseconds().build(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + // As this is a 'from' filter, ensure milliseconds are set to zero (minimum value) + calendar.set(Calendar.MILLISECOND, 0); + this.date = calendar.getTime(); } @Override diff --git a/dspace-oai/src/main/java/org/dspace/xoai/filter/DateUntilFilter.java b/dspace-oai/src/main/java/org/dspace/xoai/filter/DateUntilFilter.java index 3735cbfc7f..71519626ef 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/filter/DateUntilFilter.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/filter/DateUntilFilter.java @@ -7,9 +7,9 @@ */ package org.dspace.xoai.filter; +import java.util.Calendar; import java.util.Date; -import com.lyncode.builder.DateBuilder; import com.lyncode.xoai.dataprovider.services.api.DateProvider; import com.lyncode.xoai.dataprovider.services.impl.BaseDateProvider; import org.apache.solr.client.solrj.util.ClientUtils; @@ -24,7 +24,11 @@ public class DateUntilFilter extends DSpaceFilter { private final Date date; public DateUntilFilter(Date date) { - this.date = new DateBuilder(date).setMaxMilliseconds().build(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + // As this is a 'from' filter, ensure milliseconds are set to 999 (maximum value) + calendar.set(Calendar.MILLISECOND, 999); + this.date = calendar.getTime(); } @Override diff --git a/dspace-oai/src/main/java/org/dspace/xoai/services/impl/DSpaceServiceResolver.java b/dspace-oai/src/main/java/org/dspace/xoai/services/impl/DSpaceServiceResolver.java index d14326aca1..2666d16105 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/services/impl/DSpaceServiceResolver.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/services/impl/DSpaceServiceResolver.java @@ -9,7 +9,6 @@ package org.dspace.xoai.services.impl; import java.util.Map; -import com.lyncode.builder.MapBuilder; import com.lyncode.xoai.dataprovider.services.api.ResourceResolver; import org.dspace.xoai.services.api.ServiceResolver; import org.dspace.xoai.services.api.config.ConfigurationService; @@ -17,10 +16,9 @@ import org.dspace.xoai.services.impl.config.DSpaceConfigurationService; import org.dspace.xoai.services.impl.resources.DSpaceResourceResolver; public class DSpaceServiceResolver implements ServiceResolver { - private Map services = new MapBuilder() - .withPair(ConfigurationService.class.getName(), new DSpaceConfigurationService()) - .withPair(ResourceResolver.class.getName(), new DSpaceResourceResolver()) - .build(); + private Map services = Map.of( + ConfigurationService.class.getName(), new DSpaceConfigurationService(), + ResourceResolver.class.getName(), new DSpaceResourceResolver()); @Override public T getService(Class type) { diff --git a/dspace-oai/src/main/java/org/dspace/xoai/services/impl/xoai/DSpaceItemSolrRepository.java b/dspace-oai/src/main/java/org/dspace/xoai/services/impl/xoai/DSpaceItemSolrRepository.java index 1ec28ea358..281095e01a 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/services/impl/xoai/DSpaceItemSolrRepository.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/services/impl/xoai/DSpaceItemSolrRepository.java @@ -7,13 +7,15 @@ */ package org.dspace.xoai.services.impl.xoai; +import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Lists.transform; + import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import com.google.common.base.Function; -import com.lyncode.builder.ListBuilder; import com.lyncode.xoai.dataprovider.core.ListItemIdentifiersResult; import com.lyncode.xoai.dataprovider.core.ListItemsResults; import com.lyncode.xoai.dataprovider.data.Item; @@ -71,14 +73,14 @@ public class DSpaceItemSolrRepository extends DSpaceItemRepository { List filters, int offset, int length) { try { QueryResult queryResult = retrieveItems(filters, offset, length); - List identifierList = new ListBuilder() - .add(queryResult.getResults()) - .build(new Function() { + // transform results list from a list of Items to a list of ItemIdentifiers + List identifierList = + newArrayList(transform(queryResult.getResults(), new Function() { @Override public ItemIdentifier apply(Item elem) { return elem; } - }); + })); return new ListItemIdentifiersResult(queryResult.hasMore(), identifierList, queryResult.getTotal()); } catch (DSpaceSolrException | IOException ex) { log.error(ex.getMessage(), ex); diff --git a/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java b/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java index 73b2ae615f..784c3009c8 100644 --- a/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java +++ b/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java @@ -8,7 +8,8 @@ package org.dspace.xoai.tests.integration.xoai; -import static com.lyncode.test.matchers.xml.XPathMatchers.xPath; +import static org.dspace.xoai.tests.support.XmlMatcherBuilder.xml; +//import static com.lyncode.test.matchers.xml.XPathMatchers.xPath; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; @@ -17,6 +18,7 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamSource; import com.lyncode.xoai.util.XSLPipeline; +import org.dspace.xoai.tests.support.XmlMatcherBuilder; import org.junit.Test; import org.parboiled.common.FileUtils; @@ -31,7 +33,8 @@ public class PipelineTest { .apply(factory.newTransformer(new StreamSource(xslt))) .getTransformed()); - assertThat(output, xPath("/oai_dc:dc/dc:title", equalTo("Teste"))); + assertThat(output, oai_dc().withXPath("/oai_dc:dc/dc:title", equalTo("Teste"))); + //assertThat(output, xPath("/oai_dc:dc/dc:title", equalTo("Teste"))); input.close(); input = null; @@ -39,4 +42,11 @@ public class PipelineTest { xslt = null; output = null; } + + private XmlMatcherBuilder oai_dc() { + return xml() + .withNamespace("oai_dc", "http://www.openarchives.org/OAI/2.0/oai_dc/") + .withNamespace("dc", "http://purl.org/dc/elements/1.1/"); + } + } diff --git a/dspace-oai/src/test/java/org/dspace/xoai/tests/unit/services/impl/AbstractQueryResolverTest.java b/dspace-oai/src/test/java/org/dspace/xoai/tests/unit/services/impl/AbstractQueryResolverTest.java index 50cbf92553..9963faf494 100644 --- a/dspace-oai/src/test/java/org/dspace/xoai/tests/unit/services/impl/AbstractQueryResolverTest.java +++ b/dspace-oai/src/test/java/org/dspace/xoai/tests/unit/services/impl/AbstractQueryResolverTest.java @@ -9,9 +9,10 @@ package org.dspace.xoai.tests.unit.services.impl; import static org.mockito.Mockito.mock; +import java.util.Calendar; import java.util.Date; -import com.lyncode.builder.DateBuilder; +//import com.lyncode.builder.DateBuilder; import com.lyncode.xoai.dataprovider.services.impl.BaseDateProvider; import org.apache.solr.client.solrj.util.ClientUtils; import org.dspace.xoai.services.api.CollectionsService; @@ -59,11 +60,19 @@ public abstract class AbstractQueryResolverTest { protected String escapedFromDate(Date date) { return ClientUtils.escapeQueryChars( - baseDateProvider.format(new DateBuilder(date).setMinMilliseconds().build()).replace("Z", ".000Z")); + baseDateProvider.format(dateWithMilliseconds(date, 0)).replace("Z", ".000Z")); } protected String escapedUntilDate(Date date) { return ClientUtils.escapeQueryChars( - baseDateProvider.format(new DateBuilder(date).setMaxMilliseconds().build()).replace("Z", ".999Z")); + baseDateProvider.format(dateWithMilliseconds(date, 999)).replace("Z", ".999Z")); + } + + // Return date with specified milliseconds value + private Date dateWithMilliseconds(Date date, int milliseconds) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.MILLISECOND, milliseconds); + return calendar.getTime(); } } diff --git a/dspace/pom.xml b/dspace/pom.xml index 5a332c03c7..dc3d48f089 100644 --- a/dspace/pom.xml +++ b/dspace/pom.xml @@ -240,33 +240,7 @@ org.dspace dspace-oai - - - com.lyncode - builder-commons - - - com.google.guava - guava - - - - com.lyncode - builder-commons - 1.0.2 - - - com.google.guava - guava - - - - - com.google.guava - guava - 19.0 - diff --git a/pom.xml b/pom.xml index 74574d1084..033aff207d 100644 --- a/pom.xml +++ b/pom.xml @@ -1651,12 +1651,7 @@ com.google.guava guava - 19.0 - - - com.lyncode - builder-commons - 1.0.2 + 30.0-jre xom From d22a70611c55435c4702ef52554ce30d7e114fc3 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 1 Dec 2020 16:59:15 -0600 Subject: [PATCH 087/179] Minor cleanup. Comment correction. Remove commented out code --- .../src/main/java/org/dspace/xoai/filter/DateUntilFilter.java | 2 +- .../org/dspace/xoai/tests/integration/xoai/PipelineTest.java | 2 -- .../tests/unit/services/impl/AbstractQueryResolverTest.java | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/dspace-oai/src/main/java/org/dspace/xoai/filter/DateUntilFilter.java b/dspace-oai/src/main/java/org/dspace/xoai/filter/DateUntilFilter.java index 71519626ef..4cf0cfaf25 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/filter/DateUntilFilter.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/filter/DateUntilFilter.java @@ -26,7 +26,7 @@ public class DateUntilFilter extends DSpaceFilter { public DateUntilFilter(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); - // As this is a 'from' filter, ensure milliseconds are set to 999 (maximum value) + // As this is an 'until' filter, ensure milliseconds are set to 999 (maximum value) calendar.set(Calendar.MILLISECOND, 999); this.date = calendar.getTime(); } diff --git a/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java b/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java index 784c3009c8..de76c99245 100644 --- a/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java +++ b/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java @@ -9,7 +9,6 @@ package org.dspace.xoai.tests.integration.xoai; import static org.dspace.xoai.tests.support.XmlMatcherBuilder.xml; -//import static com.lyncode.test.matchers.xml.XPathMatchers.xPath; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; @@ -34,7 +33,6 @@ public class PipelineTest { .getTransformed()); assertThat(output, oai_dc().withXPath("/oai_dc:dc/dc:title", equalTo("Teste"))); - //assertThat(output, xPath("/oai_dc:dc/dc:title", equalTo("Teste"))); input.close(); input = null; diff --git a/dspace-oai/src/test/java/org/dspace/xoai/tests/unit/services/impl/AbstractQueryResolverTest.java b/dspace-oai/src/test/java/org/dspace/xoai/tests/unit/services/impl/AbstractQueryResolverTest.java index 9963faf494..53fc643449 100644 --- a/dspace-oai/src/test/java/org/dspace/xoai/tests/unit/services/impl/AbstractQueryResolverTest.java +++ b/dspace-oai/src/test/java/org/dspace/xoai/tests/unit/services/impl/AbstractQueryResolverTest.java @@ -12,7 +12,6 @@ import static org.mockito.Mockito.mock; import java.util.Calendar; import java.util.Date; -//import com.lyncode.builder.DateBuilder; import com.lyncode.xoai.dataprovider.services.impl.BaseDateProvider; import org.apache.solr.client.solrj.util.ClientUtils; import org.dspace.xoai.services.api.CollectionsService; From 7cabcbabbca808cd22a169d03d2d3f641f6136fb Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 13 Jan 2021 09:39:25 -0600 Subject: [PATCH 088/179] Rename to RegistryUpdater so that it comes alphabetically *after* GroupServiceInitializer as Flyway runs callbacks alphabetically --- .../{DatabaseRegistryUpdater.java => RegistryUpdater.java} | 4 ++-- .../src/main/resources/spring/spring-dspace-core-services.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename dspace-api/src/main/java/org/dspace/storage/rdbms/{DatabaseRegistryUpdater.java => RegistryUpdater.java} (97%) diff --git a/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseRegistryUpdater.java b/dspace-api/src/main/java/org/dspace/storage/rdbms/RegistryUpdater.java similarity index 97% rename from dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseRegistryUpdater.java rename to dspace-api/src/main/java/org/dspace/storage/rdbms/RegistryUpdater.java index f52d6ef2a4..ae8be0988a 100644 --- a/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseRegistryUpdater.java +++ b/dspace-api/src/main/java/org/dspace/storage/rdbms/RegistryUpdater.java @@ -47,11 +47,11 @@ import org.xml.sax.SAXException; * * @author Tim Donohue */ -public class DatabaseRegistryUpdater implements Callback { +public class RegistryUpdater implements Callback { /** * logging category */ - private static final Logger log = LoggerFactory.getLogger(DatabaseRegistryUpdater.class); + private static final Logger log = LoggerFactory.getLogger(RegistryUpdater.class); /** * Method to actually update our registries from latest configuration files. diff --git a/dspace-api/src/main/resources/spring/spring-dspace-core-services.xml b/dspace-api/src/main/resources/spring/spring-dspace-core-services.xml index 402d5d8287..6dcaa43b08 100644 --- a/dspace-api/src/main/resources/spring/spring-dspace-core-services.xml +++ b/dspace-api/src/main/resources/spring/spring-dspace-core-services.xml @@ -40,7 +40,7 @@ - + From 25b00647b9faf3451c38c949221ce3c2731805d9 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 14 Jan 2021 14:07:21 -0600 Subject: [PATCH 089/179] Workaround https://issues.apache.org/jira/browse/SOLR-12858 by ensuring EmbeddedSolrServer always uses GET instead of POST --- .../org/dspace/discovery/SolrSearchCore.java | 21 ++++++++++++++++++- .../org/dspace/discovery/SolrServiceImpl.java | 17 ++++++++------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/discovery/SolrSearchCore.java b/dspace-api/src/main/java/org/dspace/discovery/SolrSearchCore.java index f61287ac87..4de3a3f9ea 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/SolrSearchCore.java +++ b/dspace-api/src/main/java/org/dspace/discovery/SolrSearchCore.java @@ -39,10 +39,29 @@ public class SolrSearchCore { */ protected SolrClient solr = null; + /** + * Default HTTP method to use for all Solr Requests (we prefer POST). + * This REQUEST_METHOD should be used in all Solr queries, e.g. + * solSearchCore.getSolr().query(myQuery, solrSearchCore.REQUEST_METHOD); + */ + public SolrRequest.METHOD REQUEST_METHOD = SolrRequest.METHOD.POST; + + /** + * Get access to current SolrClient. If no current SolrClient exists, a new one is initialized, see initSolr(). + * @return SolrClient Solr client + */ public SolrClient getSolr() { if (solr == null) { initSolr(); } + + // If we are running Integration Tests using the EmbeddedSolrServer, we MUST override our default HTTP request + // method to use GET instead of POST (the latter is what we prefer). Unfortunately, EmbeddedSolrServer does not + // current work well with POST requests (see https://issues.apache.org/jira/browse/SOLR-12858). When that bug is + // fixed, we should remove this 'if' statement so that tests also use POST. + if (solr.getClass().getSimpleName().equals("EmbeddedSolrServer")) { + REQUEST_METHOD = SolrRequest.METHOD.GET; + } return solr; } @@ -69,7 +88,7 @@ public class SolrSearchCore { " AND " + SearchUtils.RESOURCE_ID_FIELD + ":1"); // Only return obj identifier fields in result doc solrQuery.setFields(SearchUtils.RESOURCE_TYPE_FIELD, SearchUtils.RESOURCE_ID_FIELD); - solrServer.query(solrQuery, SolrRequest.METHOD.POST); + solrServer.query(solrQuery, REQUEST_METHOD); // As long as Solr initialized, check with DatabaseUtils to see // if a reindex is in order. If so, reindex everything diff --git a/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java b/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java index a71cb664c6..fc73009644 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java @@ -36,7 +36,6 @@ import org.apache.commons.collections4.Transformer; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; import org.apache.solr.client.solrj.SolrQuery; -import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.response.FacetField; import org.apache.solr.client.solrj.response.QueryResponse; @@ -362,7 +361,8 @@ public class SolrServiceImpl implements SearchService, IndexingService { SolrQuery countQuery = new SolrQuery("*:*"); countQuery.setRows(0); // don't actually request any data // Get the total amount of results - QueryResponse totalResponse = solrSearchCore.getSolr().query(countQuery, SolrRequest.METHOD.POST); + QueryResponse totalResponse = solrSearchCore.getSolr().query(countQuery, + solrSearchCore.REQUEST_METHOD); long total = totalResponse.getResults().getNumFound(); int start = 0; @@ -378,7 +378,7 @@ public class SolrServiceImpl implements SearchService, IndexingService { // Keep looping until we hit the total number of Solr docs while (start < total) { query.setStart(start); - QueryResponse rsp = solrSearchCore.getSolr().query(query, SolrRequest.METHOD.POST); + QueryResponse rsp = solrSearchCore.getSolr().query(query, solrSearchCore.REQUEST_METHOD); SolrDocumentList docs = rsp.getResults(); for (SolrDocument doc : docs) { @@ -439,7 +439,7 @@ public class SolrServiceImpl implements SearchService, IndexingService { SolrQuery solrQuery = new SolrQuery(); solrQuery.set("spellcheck", true); solrQuery.set(SpellingParams.SPELLCHECK_BUILD, true); - solrSearchCore.getSolr().query(solrQuery, SolrRequest.METHOD.POST); + solrSearchCore.getSolr().query(solrQuery, solrSearchCore.REQUEST_METHOD); } catch (SolrServerException e) { //Make sure to also log the exception since this command is usually run from a crontab. log.error(e, e); @@ -519,7 +519,7 @@ public class SolrServiceImpl implements SearchService, IndexingService { if (solrSearchCore.getSolr() == null) { return false; } - rsp = solrSearchCore.getSolr().query(query, SolrRequest.METHOD.POST); + rsp = solrSearchCore.getSolr().query(query, solrSearchCore.REQUEST_METHOD); } catch (SolrServerException e) { throw new SearchServiceException(e.getMessage(), e); } @@ -721,7 +721,8 @@ public class SolrServiceImpl implements SearchService, IndexingService { SolrQuery solrQuery = resolveToSolrQuery(context, discoveryQuery); - QueryResponse queryResponse = solrSearchCore.getSolr().query(solrQuery, SolrRequest.METHOD.POST); + QueryResponse queryResponse = solrSearchCore.getSolr().query(solrQuery, + solrSearchCore.REQUEST_METHOD); return retrieveResult(context, discoveryQuery, queryResponse); } catch (Exception e) { @@ -1048,7 +1049,7 @@ public class SolrServiceImpl implements SearchService, IndexingService { if (filterquery != null) { solrQuery.addFilterQuery(filterquery); } - QueryResponse rsp = solrSearchCore.getSolr().query(solrQuery, SolrRequest.METHOD.POST); + QueryResponse rsp = solrSearchCore.getSolr().query(solrQuery, solrSearchCore.REQUEST_METHOD); SolrDocumentList docs = rsp.getResults(); Iterator iter = docs.iterator(); @@ -1152,7 +1153,7 @@ public class SolrServiceImpl implements SearchService, IndexingService { if (solrSearchCore.getSolr() == null) { return Collections.emptyList(); } - QueryResponse rsp = solrSearchCore.getSolr().query(solrQuery, SolrRequest.METHOD.POST); + QueryResponse rsp = solrSearchCore.getSolr().query(solrQuery, solrSearchCore.REQUEST_METHOD); NamedList mltResults = (NamedList) rsp.getResponse().get("moreLikeThis"); if (mltResults != null && mltResults.get(item.getType() + "-" + item.getID()) != null) { SolrDocumentList relatedDocs = (SolrDocumentList) mltResults.get(item.getType() + "-" + item.getID()); From 022b79cb5e99e0a7872fca8f1c79ca24c178ef62 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 14 Jan 2021 16:58:20 -0600 Subject: [PATCH 090/179] Upgrade to Solr 8.7.0. Fix dependency convergence issues. Minor fix to MockSolrServer for Solr 8 compatibility --- dspace-api/pom.xml | 160 ++++++------------ .../java/org/dspace/solr/MockSolrServer.java | 9 +- dspace-rest/pom.xml | 5 + dspace-server-webapp/pom.xml | 116 +------------ dspace-services/pom.xml | 45 ----- dspace/modules/additions/pom.xml | 3 - dspace/modules/server/pom.xml | 63 +------ pom.xml | 68 ++++---- 8 files changed, 97 insertions(+), 372 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index f1bbba2f53..9ea5499fc4 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -356,6 +356,48 @@ org.ow2.asm asm-commons + + + org.bouncycastle + bcpkix-jdk15on + + + org.bouncycastle + bcprov-jdk15on + + + + org.eclipse.jetty + jetty-alpn-java-server + + + org.eclipse.jetty + jetty-deploy + + + org.eclipse.jetty + jetty-servlet + + + org.eclipse.jetty + jetty-servlets + + + org.eclipse.jetty + jetty-webapp + + + org.eclipse.jetty + jetty-xml + + + org.eclipse.jetty.http2 + http2-common + + + org.eclipse.jetty.http2 + http2-server + @@ -524,61 +566,10 @@ test ${solr.client.version} + - commons-cli - commons-cli - - - org.eclipse.jetty - jetty-continuation - - - org.eclipse.jetty - jetty-deploy - - - org.eclipse.jetty - jetty-http - - - org.eclipse.jetty - jetty-io - - - org.eclipse.jetty - jetty-jmx - - - org.eclipse.jetty - jetty-rewrite - - - org.eclipse.jetty - jetty-security - - - org.eclipse.jetty - jetty-server - - - org.eclipse.jetty - jetty-servlet - - - org.eclipse.jetty - jetty-servlets - - - org.eclipse.jetty - jetty-util - - - org.eclipse.jetty - jetty-webapp - - - org.eclipse.jetty - jetty-xml + org.apache.commons + commons-text @@ -586,62 +577,10 @@ org.apache.solr solr-cell - + - commons-cli - commons-cli - - - org.ow2.asm - asm-commons - - - org.bouncycastle - bcpkix-jdk15on - - - org.bouncycastle - bcprov-jdk15on - - - org.eclipse.jetty - jetty-xml - - - org.eclipse.jetty - jetty-http - - - org.eclipse.jetty - jetty-servlet - - - org.eclipse.jetty - jetty-webapp - - - org.eclipse.jetty - jetty-util - - - org.eclipse.jetty - jetty-deploy - - - org.eclipse.jetty - jetty-continuation - - - org.eclipse.jetty - jetty-servlets - - - org.eclipse.jetty - jetty-io - - - org.eclipse.jetty - jetty-security + org.apache.commons + commons-text @@ -649,8 +588,6 @@ org.apache.lucene lucene-core - org.apache.lucene lucene-analyzers-icu @@ -669,7 +606,6 @@ org.apache.xmlbeans xmlbeans - 2.6.0 diff --git a/dspace-api/src/test/java/org/dspace/solr/MockSolrServer.java b/dspace-api/src/test/java/org/dspace/solr/MockSolrServer.java index 85495ca185..6254eddf55 100644 --- a/dspace-api/src/test/java/org/dspace/solr/MockSolrServer.java +++ b/dspace-api/src/test/java/org/dspace/solr/MockSolrServer.java @@ -9,6 +9,9 @@ package org.dspace.solr; import java.io.File; import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLong; @@ -157,9 +160,9 @@ public class MockSolrServer { */ private static synchronized void initSolrContainer() { if (container == null) { - String solrDir = AbstractDSpaceIntegrationTest.getDspaceDir() + File.separator + "solr"; - log.info("Initializing SOLR CoreContainer with directory " + solrDir); - container = new CoreContainer(solrDir); + Path solrDir = Paths.get(AbstractDSpaceIntegrationTest.getDspaceDir() + File.separator + "solr"); + log.info("Initializing SOLR CoreContainer with directory " + solrDir.toAbsolutePath().toString()); + container = new CoreContainer(solrDir, new Properties()); container.load(); log.info("SOLR CoreContainer initialized"); } diff --git a/dspace-rest/pom.xml b/dspace-rest/pom.xml index be80c8c159..704ddb8a39 100644 --- a/dspace-rest/pom.xml +++ b/dspace-rest/pom.xml @@ -156,6 +156,11 @@ jakarta.annotation jakarta.annotation-api + + + org.ow2.asm + asm-commons + diff --git a/dspace-server-webapp/pom.xml b/dspace-server-webapp/pom.xml index b96d161d6d..bb9384a20d 100644 --- a/dspace-server-webapp/pom.xml +++ b/dspace-server-webapp/pom.xml @@ -459,57 +459,10 @@ ${solr.client.version} test + - org.eclipse.jetty - jetty-continuation - - - org.eclipse.jetty - jetty-deploy - - - org.eclipse.jetty - jetty-http - - - org.eclipse.jetty - jetty-io - - - org.eclipse.jetty - jetty-jmx - - - org.eclipse.jetty - jetty-rewrite - - - org.eclipse.jetty - jetty-security - - - org.eclipse.jetty - jetty-server - - - org.eclipse.jetty - jetty-servlet - - - org.eclipse.jetty - jetty-servlets - - - org.eclipse.jetty - jetty-util - - - org.eclipse.jetty - jetty-webapp - - - org.eclipse.jetty - jetty-xml + org.apache.commons + commons-text @@ -518,70 +471,13 @@ solr-cell test + - org.bouncycastle - bcpkix-jdk15on - - - org.bouncycastle - bcprov-jdk15on - - - org.eclipse.jetty - jetty-continuation - - - org.eclipse.jetty - jetty-deploy - - - org.eclipse.jetty - jetty-http - - - org.eclipse.jetty - jetty-io - - - org.eclipse.jetty - jetty-jmx - - - org.eclipse.jetty - jetty-rewrite - - - org.eclipse.jetty - jetty-security - - - org.eclipse.jetty - jetty-server - - - org.eclipse.jetty - jetty-servlet - - - org.eclipse.jetty - jetty-servlets - - - org.eclipse.jetty - jetty-util - - - org.eclipse.jetty - jetty-webapp - - - org.eclipse.jetty - jetty-xml + org.apache.commons + commons-text - org.apache.lucene lucene-analyzers-icu diff --git a/dspace-services/pom.xml b/dspace-services/pom.xml index b9128654b4..83acdaf008 100644 --- a/dspace-services/pom.xml +++ b/dspace-services/pom.xml @@ -161,49 +161,4 @@ - - - - azeckoski - Aaron Zeckoski - azeckoski@gmail.com - http://wiki.sakaiproject.org/confluence/display/~aaronz - - CARET, University of Cambridge - http://caret.cam.ac.uk/ - - - architect - committer - - 0 - - - mdiggory - Mark Diggory - mdiggory@atmire.com - - architect - committer - - @mire - http://www.atmire.com - -8 - - - - - - Add Your Name Here and submit a patch! - contributor at myu.edu - http://www.myu.edu/me - My University - http://www.myu.edu - - developer - - 0 - - - diff --git a/dspace/modules/additions/pom.xml b/dspace/modules/additions/pom.xml index 4eaee1f8e2..547992b940 100644 --- a/dspace/modules/additions/pom.xml +++ b/dspace/modules/additions/pom.xml @@ -258,8 +258,6 @@ org.apache.lucene lucene-core - org.apache.lucene lucene-analyzers-icu @@ -278,7 +276,6 @@ org.apache.xmlbeans xmlbeans - 2.6.0 diff --git a/dspace/modules/server/pom.xml b/dspace/modules/server/pom.xml index 5d94c97069..36e47c7767 100644 --- a/dspace/modules/server/pom.xml +++ b/dspace/modules/server/pom.xml @@ -336,70 +336,13 @@ just adding new jar in the classloader solr-cell test + - org.bouncycastle - bcpkix-jdk15on - - - org.bouncycastle - bcprov-jdk15on - - - org.eclipse.jetty - jetty-continuation - - - org.eclipse.jetty - jetty-deploy - - - org.eclipse.jetty - jetty-http - - - org.eclipse.jetty - jetty-io - - - org.eclipse.jetty - jetty-jmx - - - org.eclipse.jetty - jetty-rewrite - - - org.eclipse.jetty - jetty-security - - - org.eclipse.jetty - jetty-server - - - org.eclipse.jetty - jetty-servlet - - - org.eclipse.jetty - jetty-servlets - - - org.eclipse.jetty - jetty-util - - - org.eclipse.jetty - jetty-webapp - - - org.eclipse.jetty - jetty-xml + org.apache.commons + commons-text - org.apache.lucene lucene-analyzers-icu diff --git a/pom.xml b/pom.xml index 033aff207d..e198cde6c8 100644 --- a/pom.xml +++ b/pom.xml @@ -25,9 +25,7 @@ 5.4.10.Final 6.0.18.Final 42.2.9 - - 7.3.1 + 8.7.0 1.2.22 2.3.4 @@ -37,7 +35,7 @@ 2.3.1 2.3.1 - 9.4.17.v20190418 + 9.4.27.v20200227 2.13.3 2.0.15 3.17 @@ -1072,26 +1070,18 @@ - - - org.apache.zookeeper - zookeeper - 3.4.14 - - org.apache.james apache-mime4j-core - 0.8.1 + 0.8.3 org.ow2.asm asm - 7.1 + 8.0.1 @@ -1259,6 +1249,11 @@ org.slf4j slf4j-log4j12 + + + org.apache.commons + commons-csv + @@ -1463,11 +1458,30 @@ org.apache.poi poi-ooxml ${poi-version} + + + + com.github.virtuald + curvesapi + + org.apache.poi poi-ooxml-schemas ${poi-version} + + + + org.apache.xmlbeans + xmlbeans + + + + + org.apache.xmlbeans + xmlbeans + 3.1.0 xalan @@ -1489,7 +1503,7 @@ com.ibm.icu icu4j - 59.1 + 62.1 com.oracle @@ -1817,29 +1831,5 @@ handle.net https://handle.net/maven - - - - - - org.apache.poi - poi-ooxml - - - stax - stax-api - - - - From 44aa1025ba5c0941ea827b22b72f1596d149ed63 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 19 Jan 2021 08:57:19 -0600 Subject: [PATCH 091/179] Update Docker for Solr v8 --- dspace/src/main/docker/README.md | 10 ++++++++++ dspace/src/main/docker/solr/Dockerfile | 26 +++++++++++--------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/dspace/src/main/docker/README.md b/dspace/src/main/docker/README.md index 6c1385034b..e1cd430be4 100644 --- a/dspace/src/main/docker/README.md +++ b/dspace/src/main/docker/README.md @@ -154,3 +154,13 @@ This image can also be rebuilt using the `../docker-compose/docker-compose-shibb ## local.cfg and test/ folder These resources are bundled into the `dspace/dspace` image at build time. + + +## Debugging Docker builds + +When updating or debugging Docker image builds, it can be useful to briefly +spin up an "intermediate container". Here's how to do that: +``` +# First find the intermediate container/image ID in your commandline logs +docker run -i -t [container-id] /bin/bash +``` diff --git a/dspace/src/main/docker/solr/Dockerfile b/dspace/src/main/docker/solr/Dockerfile index 2caf5e5fba..f6c2283db0 100644 --- a/dspace/src/main/docker/solr/Dockerfile +++ b/dspace/src/main/docker/solr/Dockerfile @@ -9,29 +9,25 @@ # Define a 'dspace' alias for our latest v7 image FROM dspace/dspace:dspace-7_x as dspace -# Pin to Solr v7 -# Note: The WORKDIR changes to /var/solr in v8 and directory layout is different -# See README at https://github.com/docker-solr/docker-solr/pull/210 -FROM solr:7 +# Pin to Solr v8.x +FROM solr:8 # Directory on 'dspace' image (see above) where DSpace is installed ENV DSPACE_INSTALL=/dspace -# Solr user +# User that Solr runs as ENV SOLR_USER=solr # Expose Solr on localhost:8983 EXPOSE 8983 8983 -WORKDIR /opt/solr/server/solr +# Solr Data Directory (NOTE: logs are in /var/solr/logs) +WORKDIR /var/solr/data USER $SOLR_USER -# Create DSpace-specific Solr cores (based on default configset provided by Solr) +# Create DSpace-specific Solr cores (under our WORKDIR) RUN \ - cp -r configsets/_default authority && \ - mkdir authority/data &&\ - cp -r configsets/_default oai && \ - mkdir oai/data &&\ - cp -r configsets/_default search && \ - mkdir search/data &&\ - cp -r configsets/_default statistics && \ - mkdir statistics/data + init-var-solr && \ + precreate-core authority && \ + precreate-core oai && \ + precreate-core search && \ + precreate-core statistics # Copy the DSpace-specific Solr schemas & configs (from our 'dspace' image) # into corresponding Solr core directory From ee466114197dd94af7c77c0195caab094126e183 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 19 Jan 2021 08:57:43 -0600 Subject: [PATCH 092/179] Update solrconfig.xml files for Solr v8 (also minor alignment correction) --- dspace/solr/authority/conf/solrconfig.xml | 4 +- dspace/solr/oai/conf/solrconfig.xml | 106 +++++++++---------- dspace/solr/search/conf/solrconfig.xml | 98 +++++++++--------- dspace/solr/statistics/conf/solrconfig.xml | 112 ++++++++++----------- 4 files changed, 160 insertions(+), 160 deletions(-) diff --git a/dspace/solr/authority/conf/solrconfig.xml b/dspace/solr/authority/conf/solrconfig.xml index 1984bb34a6..7732bc18c9 100644 --- a/dspace/solr/authority/conf/solrconfig.xml +++ b/dspace/solr/authority/conf/solrconfig.xml @@ -26,7 +26,7 @@ ${solr.abortOnConfigurationError:true} - 7.2.1 + 8.7.0 @@ -96,7 +96,7 @@ - + diff --git a/dspace/solr/oai/conf/solrconfig.xml b/dspace/solr/oai/conf/solrconfig.xml index 1a7b78e996..9561ae41c0 100644 --- a/dspace/solr/oai/conf/solrconfig.xml +++ b/dspace/solr/oai/conf/solrconfig.xml @@ -20,15 +20,15 @@ DSpace 'oai' core. For more details about configurations options that may appear in - this file, see http://wiki.apache.org/solr/SolrConfigXml. + this file, see http://wiki.apache.org/solr/SolrConfigXml. --> - 7.2.1 + 8.7.0 ${solr.data.dir:} - + @@ -49,15 +49,15 @@ ${solr.ulog.dir:} - - + + 10000 ${solr.autoCommit.maxTime:10000} - true + true - - ${solr.autoSoftCommit.maxTime:-1} + + ${solr.autoSoftCommit.maxTime:-1} @@ -74,12 +74,12 @@ size="512" initialSize="512" autowarmCount="0"/> - + - + true 20 @@ -106,9 +106,9 @@ - @@ -212,21 +212,21 @@ on - false + false 5 2 - 5 + 5 true - true + true 5 - 3 + 3 spellcheck - + @@ -236,7 +236,7 @@ - @@ -250,12 +250,12 @@ - - @@ -283,11 +283,11 @@ - explicit + explicit true - + @@ -332,10 +332,10 @@ 4 0.01 - + wordbreak - solr.WordBreakSolrSpellChecker + solr.WordBreakSolrSpellChecker name true true @@ -350,14 +350,14 @@ default wordbreak on - true + true 10 5 - 5 + 5 true - true + true 10 - 5 + 5 spellcheck @@ -405,7 +405,7 @@ features true false - + edismax text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 @@ -413,19 +413,19 @@ *:* 10 *,score - + clustering - + true false - + terms @@ -448,7 +448,7 @@ - @@ -456,7 +456,7 @@ - @@ -468,7 +468,7 @@ - @@ -477,25 +477,25 @@ - - - - - - - - - ]]> - - @@ -516,8 +516,8 @@ .,!? - - WORD @@ -531,9 +531,9 @@ text/plain; charset=UTF-8 - + - + 5 diff --git a/dspace/solr/search/conf/solrconfig.xml b/dspace/solr/search/conf/solrconfig.xml index 5e18a6a9b1..669b76db4c 100644 --- a/dspace/solr/search/conf/solrconfig.xml +++ b/dspace/solr/search/conf/solrconfig.xml @@ -20,10 +20,10 @@ DSpace 'search' core. For more details about configurations options that may appear in - this file, see http://wiki.apache.org/solr/SolrConfigXml. + this file, see http://wiki.apache.org/solr/SolrConfigXml. --> - 7.2.1 + 8.7.0 ${solr.data.dir:} - + - 32 + 100 1000 ${solr.lock.type:native} @@ -59,21 +59,21 @@ ${solr.ulog.dir:} - - + + 10000 ${solr.autoCommit.maxTime:10000} - true + true - - ${solr.autoSoftCommit.maxTime:-1} + + ${solr.autoSoftCommit.maxTime:-1} - 1024 + ${solr.max.booleanClauses:1024} - + - + true 20 @@ -113,11 +113,11 @@ 2 - + - @@ -133,7 +133,7 @@ spellcheck - + @@ -152,7 +152,7 @@ true - + explicit @@ -239,7 +239,7 @@ spellcheck - + @@ -248,7 +248,7 @@ - @@ -257,12 +257,12 @@ - - @@ -295,7 +295,7 @@ - + @@ -339,10 +339,10 @@ 4 0.01 - + wordbreak - solr.WordBreakSolrSpellChecker + solr.WordBreakSolrSpellChecker name true true @@ -356,14 +356,14 @@ default wordbreak on - true + true 10 5 - 5 + 5 true - true + true 10 - 5 + 5 spellcheck @@ -431,7 +431,7 @@ true false - + terms @@ -455,7 +455,7 @@ - @@ -463,7 +463,7 @@ - @@ -475,7 +475,7 @@ - @@ -484,25 +484,25 @@ - - - - - - - - - ]]> - - @@ -523,8 +523,8 @@ .,!? - - WORD @@ -538,7 +538,7 @@ text/plain; charset=UTF-8 - + diff --git a/dspace/solr/statistics/conf/solrconfig.xml b/dspace/solr/statistics/conf/solrconfig.xml index a11b737d0e..f0b8bcb6fb 100644 --- a/dspace/solr/statistics/conf/solrconfig.xml +++ b/dspace/solr/statistics/conf/solrconfig.xml @@ -20,15 +20,15 @@ DSpace 'statistics' core. For more details about configurations options that may appear in - this file, see http://wiki.apache.org/solr/SolrConfigXml. + this file, see http://wiki.apache.org/solr/SolrConfigXml. --> - 7.2.1 + 8.7.0 ${solr.data.dir:} - + @@ -48,15 +48,15 @@ ${solr.ulog.dir:} - - + + 10000 - ${solr.autoCommit.maxTime:900000} - true + ${solr.autoCommit.maxTime:900000} + true - - ${solr.autoSoftCommit.maxTime:-1} + + ${solr.autoSoftCommit.maxTime:-1} @@ -73,12 +73,12 @@ size="512" initialSize="512" autowarmCount="0"/> - + - + true 20 @@ -103,11 +103,11 @@ 2 - + - @@ -211,21 +211,21 @@ on - false + false 5 2 - 5 + 5 true - true + true 5 - 3 + 3 spellcheck - + @@ -240,7 +240,7 @@ - @@ -254,12 +254,12 @@ - - @@ -287,11 +287,11 @@ - explicit + explicit true - + @@ -336,10 +336,10 @@ 4 0.01 - + wordbreak - solr.WordBreakSolrSpellChecker + solr.WordBreakSolrSpellChecker name true true @@ -354,14 +354,14 @@ default wordbreak on - true + true 10 5 - 5 + 5 true - true + true 10 - 5 + 5 spellcheck @@ -417,7 +417,7 @@ *:* 10 *,score - + clustering @@ -429,7 +429,7 @@ true false - + terms @@ -453,7 +453,7 @@ - @@ -461,7 +461,7 @@ - 70 @@ -470,7 +470,7 @@ - @@ -479,25 +479,25 @@ - - - - - - - - - ]]> - - @@ -518,8 +518,8 @@ .,!? - - WORD @@ -531,19 +531,19 @@ - + uid - + - + text/plain; charset=UTF-8 - + - + 5 From ffb17f0664557941c70ca41e2588ec7b1a4b0c57 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 21 Jan 2021 11:29:57 -0600 Subject: [PATCH 093/179] Fix/Workaround for https://issues.apache.org/jira/browse/SOLR-12798 . Use Tika directly for parsing instead of ContentStreamUpdateRequest (which results in "URI is too large >8192" errors in Solr v8) --- .../indexobject/IndexFactoryImpl.java | 68 ++++++++++++++----- dspace/config/modules/discovery.cfg | 6 ++ 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexFactoryImpl.java index 2e4eb67723..c8ec93b4af 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexFactoryImpl.java @@ -14,13 +14,15 @@ import java.util.List; import org.apache.commons.collections4.ListUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.Logger; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrServerException; -import org.apache.solr.client.solrj.request.AbstractUpdateRequest; -import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest; import org.apache.solr.common.SolrInputDocument; -import org.apache.solr.common.params.ModifiableSolrParams; -import org.apache.solr.handler.extraction.ExtractingParams; +import org.apache.tika.exception.TikaException; +import org.apache.tika.metadata.Metadata; +import org.apache.tika.parser.ParseContext; +import org.apache.tika.parser.csv.TextAndCSVParser; +import org.apache.tika.sax.BodyContentHandler; import org.dspace.core.Context; import org.dspace.discovery.FullTextContentStreams; import org.dspace.discovery.IndexableObject; @@ -31,6 +33,7 @@ import org.dspace.discovery.indexobject.factory.IndexFactory; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.util.SolrUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.xml.sax.SAXException; /** * Basis factory interface implementation for indexing/retrieving any IndexableObject in the search core @@ -38,6 +41,8 @@ import org.springframework.beans.factory.annotation.Autowired; */ public abstract class IndexFactoryImpl implements IndexFactory { + private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(IndexFactoryImpl.class); + @Autowired protected List solrServiceIndexPlugins; @Autowired @@ -74,7 +79,7 @@ public abstract class IndexFactoryImpl implements * Write the document to the index under the appropriate unique identifier. * * @param doc the solr document to be written to the server - * @param streams list of bitstream content streams DiscoverQueryBuilderTest.java:285 + * @param streams list of bitstream content streams * @throws IOException A general class of exceptions produced by failed or interrupted I/O operations. */ protected void writeDocument(SolrInputDocument doc, FullTextContentStreams streams) @@ -82,24 +87,51 @@ public abstract class IndexFactoryImpl implements final SolrClient solr = solrSearchCore.getSolr(); if (solr != null) { if (streams != null && !streams.isEmpty()) { - ContentStreamUpdateRequest req = new ContentStreamUpdateRequest("/update/extract"); - req.addContentStream(streams); + // limit full text indexing to first 100,000 characters unless configured otherwise + final int charLimit = DSpaceServicesFactory.getInstance().getConfigurationService() + .getIntProperty("discovery.solr.fulltext.charLimit", + 100000); - ModifiableSolrParams params = new ModifiableSolrParams(); + // Use Tika's Text parser as the streams are always from the TEXT bundle (i.e. already extracted text) + // TODO: We may wish to consider using Tika to extract the text in the future. + TextAndCSVParser tikaParser = new TextAndCSVParser(); + BodyContentHandler tikaHandler = new BodyContentHandler(charLimit); + Metadata tikaMetadata = new Metadata(); + ParseContext tikaContext = new ParseContext(); - //req.setParam(ExtractingParams.EXTRACT_ONLY, "true"); - for (String name : doc.getFieldNames()) { - for (Object val : doc.getFieldValues(name)) { - params.add(ExtractingParams.LITERALS_PREFIX + name, val.toString()); + // Use Apache Tika to parse the full text stream + try { + tikaParser.parse(streams.getStream(), tikaHandler, tikaMetadata, tikaContext); + } catch (SAXException saxe) { + // Check if this SAXException is just a notice that this file was longer than the character limit. + // Unfortunately there is not a unique, public exception type to catch here. This error is thrown + // by Tika's WriteOutContentHandler when it encounters a document longer than the char limit + // https://github.com/apache/tika/blob/main/tika-core/src/main/java/org/apache/tika/sax/WriteOutContentHandler.java + if (saxe.getMessage().contains("limit has been reached")) { + // log that we only indexed up to that configured limit + log.info("Full text is larger than the configured limit (discovery.solr.fulltext.charLimit)." + + " Only the first " + charLimit + " characters were indexed."); + } else { + throw new IOException("Tika parsing error. Could not index full text.", saxe); + } + } catch (TikaException ex) { + throw new IOException("Tika parsing error. Could not index full text.", ex); + } + + // Write Tika metadata to "tika_meta_*" fields. + // This metadata is not very useful right now, but we'll keep it just in case it becomes more useful. + for (String name : tikaMetadata.names()) { + for (String value : tikaMetadata.getValues(name)) { + doc.addField("tika_meta_" + name, value); } } - req.setParams(params); - req.setParam(ExtractingParams.UNKNOWN_FIELD_PREFIX, "attr_"); - req.setParam(ExtractingParams.MAP_PREFIX + "content", "fulltext"); - req.setParam(ExtractingParams.EXTRACT_FORMAT, "text"); - req.setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true); - req.process(solr); + // Save (parsed) full text to "fulltext" field + doc.addField("fulltext", tikaHandler.toString()); + + // Add document & commit immediately + solr.add(doc); + solr.commit(true, true); } else { solr.add(doc); } diff --git a/dspace/config/modules/discovery.cfg b/dspace/config/modules/discovery.cfg index a310182f10..f08ab03e1d 100644 --- a/dspace/config/modules/discovery.cfg +++ b/dspace/config/modules/discovery.cfg @@ -14,6 +14,12 @@ discovery.search.server = ${solr.server}/search #Char used to ensure that the sidebar facets are case insensitive #discovery.solr.facets.split.char=\n|||\n +# Limit to number of characters indexed by Discovery/Solr in the fulltext of a document +# Default is 100,000 characters. Unlimited characters = -1 +# Be aware that setting this to a large value (or unlimited) will require more memory and space in Solr. +# Changing this value also requires reindexing all existing objects to take effect. +#discovery.solr.fulltext.charLimit=100000 + # discovery.index.ignore-variants = false # discovery.index.ignore-authority = false discovery.index.projection=dc.title,dc.contributor.*,dc.date.issued From ea0d139c73cf6ae8fbcc86e0ad91e2f725217c78 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 22 Jan 2021 12:17:44 -0600 Subject: [PATCH 094/179] Add explicit dependency on Apache Tika to avoid UnsatisfiedDependencyException warnings from Spring Boot during startup --- dspace-api/pom.xml | 5 +++++ pom.xml | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 9ea5499fc4..ebbfad25b9 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -588,6 +588,11 @@ org.apache.lucene lucene-core + + + org.apache.tika + tika-core + org.apache.lucene lucene-analyzers-icu diff --git a/pom.xml b/pom.xml index e198cde6c8..f2caa8e041 100644 --- a/pom.xml +++ b/pom.xml @@ -1213,6 +1213,12 @@ lucene-core ${solr.client.version} + + + org.apache.tika + tika-core + 1.24.1 + @@ -1234,6 +1240,7 @@ test + org.apache.ant ant From 891544a49becac227ac8ff52c33bb252d40940ba Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 27 Jan 2021 13:32:31 -0600 Subject: [PATCH 095/179] Docker bug fix. Ensure new Solr v8 data directories are kept between Docker restarts. --- docker-compose.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 6d17005fbb..88c7e86a83 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -58,10 +58,10 @@ services: stdin_open: true tty: true volumes: - - solr_authority:/opt/solr/server/solr/authority/data - - solr_oai:/opt/solr/server/solr/oai/data - - solr_search:/opt/solr/server/solr/search/data - - solr_statistics:/opt/solr/server/solr/statistics/data + - solr_authority:/var/solr/data/authority/data + - solr_oai:/var/solr/data/oai/data + - solr_search:/var/solr/data/search/data + - solr_statistics:/var/solr/data/statistics/data volumes: assetstore: pgdata: From 90050c18fa2fbc2ae5bad8b92deaca799947a4d4 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 2 Feb 2021 14:27:50 -0600 Subject: [PATCH 096/179] Minor refactors based on feedback --- .../discovery/indexobject/IndexFactoryImpl.java | 12 +++++------- .../test/java/org/dspace/solr/MockSolrServer.java | 9 ++++----- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexFactoryImpl.java index c8ec93b4af..cb500148b5 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexFactoryImpl.java @@ -86,6 +86,7 @@ public abstract class IndexFactoryImpl implements throws IOException, SolrServerException { final SolrClient solr = solrSearchCore.getSolr(); if (solr != null) { + // If full text stream(s) were passed in, we'll index them as part of the SolrInputDocument if (streams != null && !streams.isEmpty()) { // limit full text indexing to first 100,000 characters unless configured otherwise final int charLimit = DSpaceServicesFactory.getInstance().getConfigurationService() @@ -110,7 +111,7 @@ public abstract class IndexFactoryImpl implements if (saxe.getMessage().contains("limit has been reached")) { // log that we only indexed up to that configured limit log.info("Full text is larger than the configured limit (discovery.solr.fulltext.charLimit)." - + " Only the first " + charLimit + " characters were indexed."); + + " Only the first {} characters were indexed.", charLimit); } else { throw new IOException("Tika parsing error. Could not index full text.", saxe); } @@ -128,13 +129,10 @@ public abstract class IndexFactoryImpl implements // Save (parsed) full text to "fulltext" field doc.addField("fulltext", tikaHandler.toString()); - - // Add document & commit immediately - solr.add(doc); - solr.commit(true, true); - } else { - solr.add(doc); } + + // Add document to index + solr.add(doc); } } diff --git a/dspace-api/src/test/java/org/dspace/solr/MockSolrServer.java b/dspace-api/src/test/java/org/dspace/solr/MockSolrServer.java index 6254eddf55..e80d5f8e17 100644 --- a/dspace-api/src/test/java/org/dspace/solr/MockSolrServer.java +++ b/dspace-api/src/test/java/org/dspace/solr/MockSolrServer.java @@ -7,7 +7,6 @@ */ package org.dspace.solr; -import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; @@ -115,7 +114,7 @@ public class MockSolrServer { } loadedCores.put(coreName, server); - log.info("SOLR Server for core " + coreName + " initialized"); + log.info("SOLR Server for core {} initialized", coreName); } return server; } @@ -145,7 +144,7 @@ public class MockSolrServer { solrServer.close(); usersPerCore.remove(coreName); loadedCores.remove(coreName); - log.info("SOLR Server for core " + coreName + " destroyed"); + log.info("SOLR Server for core {} destroyed", coreName); } if (usersPerCore.isEmpty()) { @@ -160,8 +159,8 @@ public class MockSolrServer { */ private static synchronized void initSolrContainer() { if (container == null) { - Path solrDir = Paths.get(AbstractDSpaceIntegrationTest.getDspaceDir() + File.separator + "solr"); - log.info("Initializing SOLR CoreContainer with directory " + solrDir.toAbsolutePath().toString()); + Path solrDir = Paths.get(AbstractDSpaceIntegrationTest.getDspaceDir(), "solr"); + log.info("Initializing SOLR CoreContainer with directory {}", solrDir.toAbsolutePath().toString()); container = new CoreContainer(solrDir, new Properties()); container.load(); log.info("SOLR CoreContainer initialized"); From e33b323135d7699743fa51873c05ef2fe5336904 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 3 Feb 2021 16:32:20 -0600 Subject: [PATCH 097/179] Remove our custom Docker container for Solr. It's unreliable with Solr v8, and all the examples show to use docker-compose directly with official image. --- docker-compose.yml | 35 +++++++++++++----- dspace/src/main/docker/README.md | 26 ------------- dspace/src/main/docker/solr/Dockerfile | 37 ------------------- dspace/src/main/docker/solr/README.md | 34 ----------------- .../src/main/docker/solr/docker-compose.yml | 16 -------- 5 files changed, 26 insertions(+), 122 deletions(-) delete mode 100644 dspace/src/main/docker/solr/Dockerfile delete mode 100644 dspace/src/main/docker/solr/README.md delete mode 100644 dspace/src/main/docker/solr/docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml index 88c7e86a83..cb96dfad77 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,6 +2,7 @@ version: '3.7' networks: dspacenet: services: + # DSpace (backend) webapp container dspace: container_name: dspace image: "${DOCKER_OWNER:-dspace}/dspace:${DSPACE_VER:-dspace-7_x-test}" @@ -33,10 +34,12 @@ services: while (! /dev/null 2>&1; do sleep 1; done; /dspace/bin/dspace database migrate catalina.sh run + # DSpace database container dspacedb: container_name: dspacedb environment: PGDATA: /pgdata + # Uses a custom Postgres image with pgcrypto installed image: dspace/dspace-postgres-pgcrypto networks: dspacenet: @@ -47,9 +50,11 @@ services: tty: true volumes: - pgdata:/pgdata + # DSpace Solr container dspacesolr: container_name: dspacesolr - image: dspace/dspace-solr + # Uses official Solr image at https://hub.docker.com/_/solr/ + image: solr:8.7 networks: dspacenet: ports: @@ -57,15 +62,27 @@ services: target: 8983 stdin_open: true tty: true + working_dir: /var/solr/data volumes: - - solr_authority:/var/solr/data/authority/data - - solr_oai:/var/solr/data/oai/data - - solr_search:/var/solr/data/search/data - - solr_statistics:/var/solr/data/statistics/data + # Mount our local Solr core configs so that they are available as Solr configsets on container + - ./dspace/solr/authority:/opt/solr/server/solr/configsets/authority + - ./dspace/solr/oai:/opt/solr/server/solr/configsets/oai + - ./dspace/solr/search:/opt/solr/server/solr/configsets/search + - ./dspace/solr/statistics:/opt/solr/server/solr/configsets/statistics + # Keep Solr data directory between reboots + - solr_data:/var/solr/data + # Initialize all DSpace Solr cores using the mounted local configsets (see above), then start Solr + entrypoint: + - /bin/bash + - '-c' + - | + init-var-solr + precreate-core authority /opt/solr/server/solr/configsets/authority + precreate-core oai /opt/solr/server/solr/configsets/oai + precreate-core search /opt/solr/server/solr/configsets/search + precreate-core statistics /opt/solr/server/solr/configsets/statistics + exec solr -f volumes: assetstore: pgdata: - solr_authority: - solr_oai: - solr_search: - solr_statistics: + solr_data: diff --git a/dspace/src/main/docker/README.md b/dspace/src/main/docker/README.md index e1cd430be4..20a2fb1e6e 100644 --- a/dspace/src/main/docker/README.md +++ b/dspace/src/main/docker/README.md @@ -106,32 +106,6 @@ Admins to our DockerHub repo can publish with the following command. docker push dspace/dspace-postgres-pgcrypto:loadsql ``` -## dspace/src/main/docker/solr/Dockerfile - -This is a standalone Solr image containing DSpace Solr cores & schemas required by DSpace 7. - -**WARNING:** Rebuilding this image first **requires** rebuilding `dspace-7_x` (i.e. `Dockerfile` listed above), -as this Solr image copies the latest DSpace-specific Solr schemas & settings from that other image. - -``` -# First, rebuild dspace-7_x to grab the latest Solr configs -cd [src] -docker build -t dspace/dspace:dspace-7_x -f Dockerfile . - -# Then, rebuild dspace-solr based on that build of DSpace 7. -cd dspace/src/main/docker/solr -docker build -t dspace/dspace-solr . -``` - -**This image is built manually.** It should be rebuilt when Solr schemas change or as new releases of Solr are incorporated. - -This file was introduced for DSpace 7. - -Admins to our DockerHub repo can publish with the following command. -``` -docker push dspace/dspace-solr -``` - ## dspace/src/main/docker/dspace-shibboleth/Dockerfile This is a test / demo image which provides an Apache HTTPD proxy (in front of Tomcat) diff --git a/dspace/src/main/docker/solr/Dockerfile b/dspace/src/main/docker/solr/Dockerfile deleted file mode 100644 index f6c2283db0..0000000000 --- a/dspace/src/main/docker/solr/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -# -# The contents of this file are subject to the license and copyright -# detailed in the LICENSE and NOTICE files at the root of the source -# tree and available online at -# -# http://www.dspace.org/license/ -# - -# Define a 'dspace' alias for our latest v7 image -FROM dspace/dspace:dspace-7_x as dspace - -# Pin to Solr v8.x -FROM solr:8 -# Directory on 'dspace' image (see above) where DSpace is installed -ENV DSPACE_INSTALL=/dspace -# User that Solr runs as -ENV SOLR_USER=solr -# Expose Solr on localhost:8983 -EXPOSE 8983 8983 - -# Solr Data Directory (NOTE: logs are in /var/solr/logs) -WORKDIR /var/solr/data -USER $SOLR_USER -# Create DSpace-specific Solr cores (under our WORKDIR) -RUN \ - init-var-solr && \ - precreate-core authority && \ - precreate-core oai && \ - precreate-core search && \ - precreate-core statistics - -# Copy the DSpace-specific Solr schemas & configs (from our 'dspace' image) -# into corresponding Solr core directory -COPY --from=dspace --chown=$SOLR_USER:$SOLR_USER $DSPACE_INSTALL/solr/authority authority/ -COPY --from=dspace --chown=$SOLR_USER:$SOLR_USER $DSPACE_INSTALL/solr/oai oai/ -COPY --from=dspace --chown=$SOLR_USER:$SOLR_USER $DSPACE_INSTALL/solr/search search/ -COPY --from=dspace --chown=$SOLR_USER:$SOLR_USER $DSPACE_INSTALL/solr/statistics statistics/ diff --git a/dspace/src/main/docker/solr/README.md b/dspace/src/main/docker/solr/README.md deleted file mode 100644 index a78e7e710e..0000000000 --- a/dspace/src/main/docker/solr/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Solr Dockerfile for DSpace 7 - -## Build Instructions - -From DSPACE-SRC dir -``` -docker build -t dspace/dspace-solr -f dspace/src/main/docker/solr/Dockerfile . -``` - -## Test Instructions - -From DSPACE-SRC dir -``` -docker-compose -f dspace/src/main/docker/solr/docker-compose.yml up -``` - -Open http://localhost:8983/solr - -## Push Instructions - -The following command requires push access to dspace on dockerhub. -``` -docker push dspace/dspace-solr -``` - -## Testing with DSpace - -_The following PR will be needed to test https://github.com/DSpace-Labs/DSpace-Docker-Images/pull/79_ - -A new solr volume will be needed for this test. Please delete any pre-existing DSpace 7 solr volumes. - -``` -docker-compose -p d7 -f docker-compose.yml -f d7.override.yml up -d -``` diff --git a/dspace/src/main/docker/solr/docker-compose.yml b/dspace/src/main/docker/solr/docker-compose.yml deleted file mode 100644 index adbd9d1d24..0000000000 --- a/dspace/src/main/docker/solr/docker-compose.yml +++ /dev/null @@ -1,16 +0,0 @@ -# -# The contents of this file are subject to the license and copyright -# detailed in the LICENSE and NOTICE files at the root of the source -# tree and available online at -# -# http://www.dspace.org/license/ -# - -version: "3.3" - -services: - solr: - image: dspace/dspace-solr - container_name: solr - ports: - - "8983:8983" From 781456fadb76917b48cfad52ab42e59759f81ce2 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 3 Feb 2021 16:35:05 -0600 Subject: [PATCH 098/179] Upgrade Jetty to avoid security warnings from Snyk. Also fixes GitHub security alert --- dspace-api/pom.xml | 41 +++++++++++++++++++++++++++++++++++ dspace-oai/pom.xml | 7 ------ dspace-server-webapp/pom.xml | 31 +++++++++++++++++++++----- dspace/modules/server/pom.xml | 13 +++++++++++ pom.xml | 4 ++-- 5 files changed, 82 insertions(+), 14 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index ebbfad25b9..09dd4a049c 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -557,6 +557,21 @@ org.apache.solr solr-solrj ${solr.client.version} + + + + org.eclipse.jetty + jetty-http + + + org.eclipse.jetty + jetty-io + + + org.eclipse.jetty + jetty-util + + @@ -571,6 +586,19 @@ org.apache.commons commons-text + + + org.eclipse.jetty + jetty-http + + + org.eclipse.jetty + jetty-io + + + org.eclipse.jetty + jetty-util + @@ -582,6 +610,19 @@ org.apache.commons commons-text + + + org.eclipse.jetty + jetty-http + + + org.eclipse.jetty + jetty-io + + + org.eclipse.jetty + jetty-util + diff --git a/dspace-oai/pom.xml b/dspace-oai/pom.xml index 1e71652cc7..c6946792c1 100644 --- a/dspace-oai/pom.xml +++ b/dspace-oai/pom.xml @@ -169,13 +169,6 @@ dspace-api - - - org.apache.solr - solr-solrj - ${solr.client.version} - - javax.servlet diff --git a/dspace-server-webapp/pom.xml b/dspace-server-webapp/pom.xml index bb9384a20d..5e17518a5e 100644 --- a/dspace-server-webapp/pom.xml +++ b/dspace-server-webapp/pom.xml @@ -401,11 +401,6 @@ nimbus-jose-jwt ${nimbus-jose-jwt.version} - - org.apache.solr - solr-solrj - ${solr.client.version} - @@ -464,6 +459,19 @@ org.apache.commons commons-text + + + org.eclipse.jetty + jetty-http + + + org.eclipse.jetty + jetty-io + + + org.eclipse.jetty + jetty-util + @@ -476,6 +484,19 @@ org.apache.commons commons-text + + + org.eclipse.jetty + jetty-http + + + org.eclipse.jetty + jetty-io + + + org.eclipse.jetty + jetty-util + diff --git a/dspace/modules/server/pom.xml b/dspace/modules/server/pom.xml index 36e47c7767..b3ac79e972 100644 --- a/dspace/modules/server/pom.xml +++ b/dspace/modules/server/pom.xml @@ -341,6 +341,19 @@ just adding new jar in the classloader org.apache.commons commons-text + + + org.eclipse.jetty + jetty-http + + + org.eclipse.jetty + jetty-io + + + org.eclipse.jetty + jetty-util + diff --git a/pom.xml b/pom.xml index f2caa8e041..c92e614a2d 100644 --- a/pom.xml +++ b/pom.xml @@ -34,8 +34,8 @@ 1.3.2 2.3.1 2.3.1 - - 9.4.27.v20200227 + + 9.4.35.v20201120 2.13.3 2.0.15 3.17 From 4394d4bcca489c4c97e7dee6b4f406b36c427aea Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 4 Feb 2021 16:19:19 -0600 Subject: [PATCH 099/179] Ensure InputStream is closed --- .../org/dspace/discovery/indexobject/IndexFactoryImpl.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexFactoryImpl.java index cb500148b5..8660bbebc7 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/IndexFactoryImpl.java @@ -8,6 +8,7 @@ package org.dspace.discovery.indexobject; import java.io.IOException; +import java.io.InputStream; import java.sql.SQLException; import java.util.Date; import java.util.List; @@ -100,9 +101,9 @@ public abstract class IndexFactoryImpl implements Metadata tikaMetadata = new Metadata(); ParseContext tikaContext = new ParseContext(); - // Use Apache Tika to parse the full text stream - try { - tikaParser.parse(streams.getStream(), tikaHandler, tikaMetadata, tikaContext); + // Use Apache Tika to parse the full text stream(s) + try (InputStream fullTextStreams = streams.getStream()) { + tikaParser.parse(fullTextStreams, tikaHandler, tikaMetadata, tikaContext); } catch (SAXException saxe) { // Check if this SAXException is just a notice that this file was longer than the character limit. // Unfortunately there is not a unique, public exception type to catch here. This error is thrown From a55acc23798c8eff9384104b79cbdca3a9bfeac2 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Mon, 22 Feb 2021 16:33:39 -0600 Subject: [PATCH 100/179] Cleanup ununsed configurations --- dspace/config/dc2mods.cfg | 71 --- dspace/config/dspace.cfg | 564 +----------------- dspace/config/modules/altmetrics.cfg | 8 +- dspace/config/modules/bulkedit.cfg | 1 + dspace/config/modules/controlpanel.cfg | 21 - dspace/config/modules/curate.cfg | 4 - dspace/config/modules/fetchccdata.cfg | 18 - dspace/config/modules/google-analytics.cfg | 4 +- dspace/config/modules/publication-lookup.cfg | 15 - dspace/config/modules/rest.cfg | 14 +- dspace/config/modules/submission-curation.cfg | 1 + dspace/config/modules/sword-client.cfg | 5 +- dspace/config/modules/versioning.cfg | 5 +- dspace/config/news-side.html | 3 - dspace/config/news-top.html | 3 - 15 files changed, 51 insertions(+), 686 deletions(-) delete mode 100644 dspace/config/dc2mods.cfg delete mode 100644 dspace/config/modules/controlpanel.cfg delete mode 100644 dspace/config/modules/fetchccdata.cfg delete mode 100644 dspace/config/modules/publication-lookup.cfg delete mode 100644 dspace/config/news-side.html delete mode 100644 dspace/config/news-top.html diff --git a/dspace/config/dc2mods.cfg b/dspace/config/dc2mods.cfg deleted file mode 100644 index aae579a796..0000000000 --- a/dspace/config/dc2mods.cfg +++ /dev/null @@ -1,71 +0,0 @@ -# DC Lib -> MODS mapping - -# Very simple, might not work - - -contributor.advisor = advisor%s -contributor.author = author%s -contributor.editor = editor%s -contributor.illustrator = illustrator%s -contributor.other = other%s -contributor = %s -coverage.spatial = %s -coverage.temporal = %s -creator = %s -date.accessioned = %s -date.available = %s -date.copyright = %s -date.created = %s -date.issued = %s -date.submitted = %s -date = %s -description.abstract = %s -description.provenance = %s -description.sponsorship = %s -description.statementofresponsibility = %s -description.tableofcontents = %s -description.uri = %s -description = %s -format.extent = %s -format.medium = %s -format.mimetype = %s -format = %s -identifier.citation = %s -identifier.govdoc = %s -identifier.isbn = %s -identifier.ismn = %s -identifier.issn = %s -identifier.other = %s -identifier.sici = %s -identifier.uri = %s -identifier = %s -language.iso = %s -language = %s -publisher = %s -relation.haspart = %s -relation.hasversion = %s -relation.isbasedon = %s -relation.isformatof = %s -relation.ispartof = %s -relation.ispartofseries = %s -relation.isreferencedby = %s -relation.isreplacedby = %s -relation.isversionof = %s -relation.replaces = %s -relation.requires = %s -relation.uri = %s -relation = %s -rights.uri = %s -rights = %s -source.uri = %s -source = %s -subject.classification = %s -subject.ddc = %s -subject.lcc = %s -subject.lcsh = %s -subject.mesh = %s -subject.other = %s -subject = %s -title.alternative = %s -title = %s -type = %s diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index 1470c99067..273d85b47b 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -3,10 +3,7 @@ # # NOTE: The DSpace Configuration File is separated into several sections: # * General Configurations -# * JSPUI & XMLUI Configurations -# * JSPUI Specific Configurations -# * XMLUI Specific Configurations -# +# * UI Configurations #------------------------------------------------------------------# #------------------GENERAL CONFIGURATIONS--------------------------# @@ -116,6 +113,7 @@ mail.from.address = dspace-noreply@myu.edu # When feedback is submitted via the Feedback form, it is sent to this address # Currently limited to one recipient! +# TODO: UNSUPPORTED in DSpace 7.0 feedback.recipient = dspace-help@myu.edu # General site administration (Webmaster) e-mail @@ -135,7 +133,7 @@ mail.charset = UTF-8 # A comma-separated list of hostnames that are allowed to refer browsers to email forms. # Default behaviour is to accept referrals only from dspace.hostname -# TODO: Needs removal/replacement. No longer used in DSpace 7 codebase and dspace.hostname config no longer exists. +# TODO: UNSUPPORTED in DSpace 7.0 #mail.allowed.referrers = ${dspace.hostname} # Pass extra settings to the Java mail library. Comma-separated, equals sign between @@ -176,6 +174,7 @@ mail.message.headers = charset # Override default log4j configuration file # You may provide your own configuration here, existing alternatives are: # log.init.config = ${dspace.dir}/config/log4j2-console.xml +# TODO: WHERE IS THIS USED? log.init.config = ${dspace.dir}/config/log4j2.xml # All other log4j settings moved to config/log4j2.xml @@ -220,10 +219,7 @@ identifier.doi.namespaceseparator = dspace/ # [dspace]/config/spring/api/discovery.xml # # See also the Discovery Documentation: -# https://wiki.duraspace.org/display/DSDOC6x/Discovery -# -# Underlying Apache Solr configurations may also be tweaked at: -# [dspace]/solr/search/conf/ +# https://wiki.lyrasis.org/display/DSDOC7x/Discovery ##### Handle settings ###### @@ -241,9 +237,8 @@ handle.canonical.prefix = ${dspace.ui.url}/handle/ # handle.canonical.prefix = http://hdl.handle.net/ # handle.canonical.prefix = https://hdl.handle.net/ # -# Note that this will not alter dc.identifer.uri metadata for existing -# items (only for subsequent submissions), but it will alter the URL -# in JSPUI's 'identifier' message on item record pages for existing items. +# Note that this will not alter dc.identifier.uri metadata for existing +# items (only for subsequent submissions). # CNRI Handle prefix # (Defaults to a dummy/fake prefix of 123456789) @@ -801,10 +796,9 @@ registry.metadata.load = dspace-types.xml #---------------------------------------------------------------# -#--------------JSPUI & XMLUI CONFIGURATIONS---------------------# +#-----------------UI-Related CONFIGURATIONS---------------------# #---------------------------------------------------------------# -# These configs are used by both JSP and XML User Interfaces, # -# except where explicitly stated otherwise. # +# These configs are used primarily by the User Interface # #---------------------------------------------------------------# # Determine if super administrators (those whom are in the Administrators group) @@ -814,16 +808,16 @@ registry.metadata.load = dspace-types.xml #webui.user.assumelogin = true # whether to display the contents of the licence bundle (often just the deposit -# licence in standard DSpace installation +# licence in standard DSpace installation) +# TODO: UNSUPPORTED in DSpace 7.0 webui.licence_bundle.show = false ##### Hide Item Metadata Fields ##### # Fields named here are hidden in the following places UNLESS the # logged-in user is an Administrator: -# 1. XMLUI metadata XML view, and Item splash pages (long and short views). -# 2. JSPUI Item splash pages -# 3. RDF (every where as there is currently no possibility to authenticate) -# 4. OAI (every where as there is currently no possibility to authenticate) +# 1. REST API (and therefore UI) +# 2. RDF (every where as there is currently no possibility to authenticate) +# 3. OAI (every where as there is currently no possibility to authenticate) # Attention: You need to rebuild the OAI SOLR index after every change of # this property. Run [dspace-install]/bin/dspace oai import -c to do so. # @@ -837,27 +831,11 @@ metadata.hide.dc.description.provenance = true ##### Settings for Submission Process ##### -# Should the submit UI block submissions marked as theses? -webui.submit.blocktheses = false - # Whether or not we REQUIRE that a file be uploaded # during the 'Upload' step in the submission process # Defaults to true; If set to 'false', submitter has option to skip upload #webui.submit.upload.required = true -# If the browser supports it, JSPUI uses html5 File API to enhance file upload. -# If this property is set to false the enhanced file upload is not used even -# if the browser would support it. -#webui.submit.upload.html5 = true - -# Whether or not to use the 'advanced' form of the access step. -# Defaults to false, ie the simple form is used. -#webui.submission.restrictstep.enableAdvancedForm = false - -# Special Group for UI: all the groups nested inside this group -# will be loaded in the multiple select list of the RestrictStep -#webui.submission.restrictstep.groups = SubmissionAdmin - #### Creative Commons settings ###### # The url to the web service API @@ -879,9 +857,6 @@ cc.submit.setname = true # Store license bitstream (RDF license text) during web submission cc.submit.addbitstream = true -# ONLY JSPUI, enable Creative Commons admin -webui.submit.enable-cc = false - # A list of license classes that should be excluded from selection process # class names - comma-separated list - must exactly match what service returns. # At time of implementation, these are: @@ -907,44 +882,15 @@ cc.license.locale = en ##### Settings for Thumbnail creation ##### -# whether to display thumbnails on browse and search results pages (1.2+) -# If you have customised the Browse columnlist, then you must also -# include a 'thumbnail' column in your configuration (1.5+) -# (This configuration is not used by XMLUI. To show thumbnails in the -# XMLUI, you just need to create a theme which displays them) -webui.browse.thumbnail.show = false - -# max dimensions of the browse/search thumbs. Must be <= thumbnail.maxwidth -# and thumbnail.maxheight. Only need to be set if required to be smaller than -# dimension of thumbnails generated by mediafilter (1.2+) -#webui.browse.thumbnail.maxheight = 80 -#webui.browse.thumbnail.maxwidth = 80 - -# whether to display the thumb against each bitstream (1.2+) -# (This configuration is not used by XMLUI. To show thumbnails in the -# XMLUI, you just need to create a theme which displays them) -webui.item.thumbnail.show = true - -# where should clicking on a thumbnail from browse/search take the user -# Only values currently supported are "item" and "bitstream" -#webui.browse.thumbnail.linkbehaviour = item - # maximum width and height of generated thumbnails thumbnail.maxwidth = 80 thumbnail.maxheight = 80 # Blur before scaling. A little blur before scaling does wonders for keeping -# moire in check. +# more in check. (Only used by JPEGFilter) thumbnail.blurring = true -# High quality scaling option. Setting to true can dramatically increase -# image quality, but it takes longer to create thumbnails. -thumbnail.hqscaling = true - - -#### Settings for Item Preview #### - -webui.preview.enabled = false +#### Settings for BrandedPreviewJPEGFilter #### # max dimensions of the preview image webui.preview.maxwidth = 600 webui.preview.maxheight = 600 @@ -975,15 +921,6 @@ webui.preview.brand.fontpoint = 12 ##### Settings for item count (strength) information #### -# Whether to display collection and community strengths (i.e. item counts) -# XMLUI only makes strengths available to themes if this is set to true! -# To show strengths in the XMLUI, you also need to create or use a theme which -# displays them. -webui.strengths.show = false - -# if showing strengths, should they be counted in real time or -# fetched from cache? -# # Counts fetched in real time will perform an actual count of the # index contents every time a page with this feature is requested, # which may not scale as well as a cached count. @@ -1082,7 +1019,7 @@ webui.browse.index.4 = subject:metadata:dc.subject.*:text # where n is the index number from the above options # Default value is false. If no option exists for a specific index, it is assumed to be false. # Changes to this option do NOT require re-indexing of discovery. -# +# TODO: UNSUPPORTED IN DSpace 7.0 #webui.browse.index.tagcloud.4 = true # Set the options for what can be sorted by @@ -1125,32 +1062,12 @@ webui.itemlist.sort-option.3 = dateaccessioned:dc.date.accessioned:date # to the default, however, if you do not explicitly redefine a datatype, then the # default will still be used in addition to the datatypes you do specify. # -# As of 1.5.2, the multi-lingual MARC 21 title ordering is configured as default. +# The multi-lingual MARC 21 title ordering is configured as default. # To use the previous title ordering, comment out the configuration below plugin.named.org.dspace.sort.OrderFormatDelegate= \ org.dspace.sort.OrderFormatTitleMarc21=title -## Set the options for how authors are displayed in the browse listing - -# Define which field is the author/editor etc listing. This should be listed in the -# field webui.itemlist.columns, otherwise it will have no effect. -# This cannot be a field already marked out as a title or a date, as this -# will also have no effect. This is used in conjunction with the -# webui.browse.author-limit field below, to truncate author lists. For -# configuring links to author publication lists use webui.browse.link below. -# (This setting is not used by the XMLUI as it is controlled by your theme) -# -# webui.browse.author-field = dc.contributor.* - -# define how many authors to display before truncating and completing with "et al" -# (or language pack specific alternative) -# -# Use -1 for unlimited (which is what will be used if this option -# is omitted) -# -# webui.browse.author-limit = 3 - # which fields should link to other browse listings. This should associated # the name of one of the above browse indices with a metadata field listed # in above. The form is: @@ -1168,12 +1085,9 @@ plugin.named.org.dspace.sort.OrderFormatDelegate= \ # # The default below defines the authors to link to other publications by that author # +# TODO: UNSUPPORTED in DSpace 7.0 webui.browse.link.1 = author:dc.contributor.* -### Render scientific formulas symbols in view/browse -# Use MathJax to render properly encoded text formulas to be visual for people -#webui.browse.render-scientific-formulas = true - #### Display browse frequencies # # webui.browse.metadata.show-freq. = true | false @@ -1185,98 +1099,6 @@ webui.browse.link.1 = author:dc.contributor.* # webui.browse.metadata.show-freq.3 = false # webui.browse.metadata.show-freq.4 = true -#### Additional configuration for Recent Submissions code #### - -# the sort option name (from webui.itemlist.sort-option above) to use for -# displaying recent submissions. (this -# is used by the Recent Submissions system and any other time based -# browse query such as FeedServlet) -# (Only used by JSPUI) -recent.submissions.sort-option = dateaccessioned - -# how many recent submissions should be displayed at any one time -# Set to 0 since discovery uses a separate configuration for this -# (Only used by JSPUI) -recent.submissions.count = 0 - -# name of the browse index to display collection's items. -# You can set a "item" type of browse index only. -# default = title -#webui.collectionhome.browse-name = title - -# how mamy items should be displayed per page in collection home page -# default = 20 -#webui.collectionhome.perpage = 20 - -# whether does use "dateaccessioned" as a sort option -# If true and the sort option "dateaccessioned" exists, use "dateaccessioned" as a sort option. -# Otherwise use the sort option pertaining the specified browse index. -# default = true -#webui.collectionhome.use.dateaccessioned = true - -# tell the community and collection pages that we are using the Recent -# Submissions code -#plugin.sequence.org.dspace.plugin.SiteHomeProcessor = \ -# org.dspace.app.webui.components.TopCommunitiesSiteProcessor,\ -# org.dspace.app.webui.components.RecentSiteSubmissions - -#plugin.sequence.org.dspace.plugin.CommunityHomeProcessor = \ -# org.dspace.app.webui.components.RecentCommunitySubmissions - -#plugin.sequence.org.dspace.plugin.CollectionHomeProcessor = \ -# org.dspace.app.webui.components.RecentCollectionSubmissions,\ -# org.dspace.app.webui.components.CollectionItemList - -#### JSPUI Discovery (extra Discovery setting that applies only to JSPUI) #### -# The legacy JSPUI Lucene search provider deprecated in DSpace 4.0 -# (org.dspace.app.webui.search.LuceneSearchRequestProcessor) has been removed -# in DSpace 6.0. -# The default since DSpace 4.0 is to use the Discovery search provider -plugin.single.org.dspace.app.webui.search.SearchRequestProcessor = \ - org.dspace.app.webui.discovery.DiscoverySearchRequestProcessor - -#### XMLUI Discovery (extra Discovery setting that applies only to XMLUI) #### -# The legacy XMLUI Lucene search provider deprecated in DSpace 4.0 -# (org.dspace.app.xmlui.aspect.administrative.mapper.LuceneSearchRequestProcessor) -# has been removed in DSpace 6.0. -# The default since DSpace 4.0 is to use the Discovery search provider -plugin.single.org.dspace.app.xmlui.aspect.administrative.mapper.SearchRequestProcessor = \ - org.dspace.app.xmlui.aspect.administrative.mapper.DiscoverySearchRequestProcessor - -#### Sidebar Facets #### -# to show facets on the site home page, community, collection -# comment out the following lines if you disable Discovery or don't want -# to show facets on side bars -# TagCloudProcessor is responsible for displaying a tag-cloud facet on the -# site home page, community or collection home page -plugin.sequence.org.dspace.plugin.CommunityHomeProcessor = \ - org.dspace.app.webui.components.RecentCommunitySubmissions,\ - org.dspace.app.webui.discovery.SideBarFacetProcessor -# org.dspace.app.webui.tagcloud.TagCloudProcessor - -plugin.sequence.org.dspace.plugin.CollectionHomeProcessor = \ - org.dspace.app.webui.components.CollectionItemList,\ - org.dspace.app.webui.discovery.SideBarFacetProcessor -# org.dspace.app.webui.tagcloud.TagCloudProcessor -# org.dspace.app.webui.components.RecentCollectionSubmissions,\ - -plugin.sequence.org.dspace.plugin.SiteHomeProcessor = \ - org.dspace.app.webui.components.TopCommunitiesSiteProcessor,\ - org.dspace.app.webui.components.RecentSiteSubmissions,\ - org.dspace.app.webui.discovery.SideBarFacetProcessor -# org.dspace.app.webui.tagcloud.TagCloudProcessor - -#### JSON JSPUI Request Handler #### -# define any JSON handler here -# -# comment out this line if you disable Discovery -plugin.named.org.dspace.app.webui.json.JSONRequest = \ - org.dspace.app.webui.discovery.DiscoveryJSONRequest = discovery,\ - org.dspace.app.webui.json.SubmissionLookupJSONRequest = submissionLookup,\ - org.dspace.app.webui.json.UploadProgressJSON = uploadProgress,\ - org.dspace.app.webui.handle.HandleJSONResolver = hdlresolver,\ - org.dspace.app.webui.json.CreativeCommonsJSONRequest = creativecommons - ### i18n - Locales / Language #### # Default Locale # A Locale in the form country or country_language or country_language_variant @@ -1286,7 +1108,8 @@ default.locale = en # All the Locales, that are supported by this instance of DSpace # A comma-separated list of Locales. All types of Locales country, country_language, country_language_variant # Note that the appropriate file are present, especially that all the Messages_x.properties are there -# may be used, e. g: webui.supported.locales = en, de +# may be used, e.g: +# webui.supported.locales = en, de #### Submission License substitution variables #### # it is possible include contextual information in the submission license using substitution variables @@ -1297,6 +1120,7 @@ plugin.named.org.dspace.content.license.LicenseArgumentFormatter = \ org.dspace.content.license.SimpleDSpaceObjectLicenseFormatter = eperson #### Syndication Feed (RSS) Settings ###### +# TODO: UNSUPPORTED in DSpace 7.0. Will be added in a later release # enable syndication feeds - links display on community and collection home pages # (This setting is not used by XMLUI, as you enable feeds in your theme) @@ -1410,12 +1234,11 @@ websvc.opensearch.formats = atom,rss # # Set the max size of a bitstream that can be served inline # Use -1 to force all bitstream to be served inline -# The 'webui.*' setting is for the JSPUI, and -# the 'xmlui.*' setting is for the XMLUI webui.content_disposition_threshold = 8388608 #### Multi-file HTML document/site settings ##### +# TODO: UNSUPPORTED in DSpace 7.0. May be re-added in a later release # # When serving up composite HTML items, how deep can the request be for us to # serve up a file with the same name? @@ -1429,12 +1252,7 @@ webui.content_disposition_threshold = 8388608 # If webui.html.max-depth-guess is zero, the request filename and path must # always exactly match the bitstream name. Default value is 3. # -# The 'webui.*' setting is for the JSPUI, and -# the 'xmlui.*' setting is for the XMLUI -# # webui.html.max-depth-guess = 3 -# xmlui.html.max-depth-guess = 3 - #### Sitemap settings ##### # the directory where the generated sitemaps are stored @@ -1491,15 +1309,14 @@ orcid.api.url = https://pub.orcid.org/v3.0 orcid.url = https://orcid.org/ # ORCID Credentials -# Your public or member API Credentials, see +# Your public or member API Credentials, see # https://orcid.org/content/register-client-application-0 -orcid.clientid = -orcid.clientsecret = +orcid.clientid = +orcid.clientsecret = #ORCID JWT Endpoint orcid.oauth.url = https://orcid.org/oauth/token - ## The DCInputAuthority plugin is automatically configured with every ## value-pairs element in input-forms.xml, namely: ## common_identifiers, common_types, common_iso_languages @@ -1539,7 +1356,6 @@ authority.minconfidence = ambiguous #choices.plugin.dc.contributor.author = SolrAuthorAuthority #choices.presentation.dc.contributor.author = authorLookup #authority.controlled.dc.contributor.author = true -# #authority.author.indexer.field.1=dc.contributor.author ## @@ -1555,45 +1371,10 @@ authority.minconfidence = ambiguous #vocabulary.plugin.srsc.hierarchy.suggest = true #vocabulary.plugin.srsc.delimiter = "::" -# Change number of choices shown in the select in Choices lookup popup -#xmlui.lookup.select.size = 12 - - -#### Ordering of bitstreams #### - -## Specify the ordering that bitstreams are listed. -## -## Bitstream field to sort on. Values: sequence_id or name. Default: sequence_id -webui.bitstream.order.field = bitstream_order - -## Direction of sorting order. Values: DESC or ASC. Default: ASC -#webui.bitstream.order.direction = ASC - - ##### Google Scholar Metadata Configuration ##### google-metadata.config = ${dspace.dir}/config/crosswalks/google-metadata.properties google-metadata.enable = true -#---------------------------------------------------------------# -#--------------JSPUI SPECIFIC CONFIGURATIONS--------------------# -#---------------------------------------------------------------# -# These configs are only used by the JSP User Interface # -#---------------------------------------------------------------# -##### JSPUI Layout ##### -# set this value if you want to use a diffent main template. -# The value must match the name of a subfolder of dspace-jspui/src/main/webapp/layout -# jspui.template.name = - -##### Show community or collection logo in list ##### -# jspui.home-page.logos = true -# jspui.community-home.logos = true -# jspui.community-list.logos = true - -##### Item Home Processor ##### - -plugin.sequence.org.dspace.plugin.ItemHomeProcessor = \ - org.dspace.app.webui.components.VersioningItemHome - ##### Upload File settings ##### # Where to temporarily store uploaded files @@ -1602,8 +1383,8 @@ upload.temp.dir = ${dspace.dir}/upload ###### Statistical Report Configuration Settings ###### # should the stats be publicly available? should be set to false if you only -# want administrators to access the stats, or you do not intend to generate -# any +# want administrators to access the stats, or you do not intend to generate any +# TODO: UNSUPPORTED in DSpace 7.0 report.public = false # directory where live reports are stored @@ -1612,110 +1393,6 @@ report.dir = ${dspace.dir}/reports/ # directory where logs are stored log.report.dir = ${dspace.dir}/log - -###### Web Interface Settings ###### - - -# Customise the DC metadata fields to show in the default simple item view. -# -# The form is .[.|.*][(date)|(link)|(nobreakline)], ... -# -# For example: -# dc.title = Dublin Core element 'title' (unqualified) -# dc.title.alternative = DC element 'title', qualifier 'alternative' -# dc.title.* = All fields with Dublin Core element 'title' -# (any or no qualifier) -# dc.identifier.uri(link) = DC identifier.uri, render as a link -# dc.date.issued(date) = DC date.issued, render as a date -# dc.subject(nobreakline) = DC subject.keyword, rendered as separated values -# (see also webui.itemdisplay.nobreakline.separator option) -# dc.language(inputform) = If the dc.language is in a controlled vocabulary, then the displayed value will be shown based on the stored value from the value-pairs-name in input forms. -# The input-forms will be loaded based on the session locale. If the displayed value is not found, then the value will be shown as is. -# "link/date" options can be combined with "nobreakline" option using a space among them i.e "dc.identifier.uri(link nobreakline)" -# -# If an item has no value for a particular field, it won't be displayed. -# The name of the field for display will be drawn from the current UI -# dictionary, using the key: -# -# "metadata. -
- - diff --git a/dspace/solr/authority/conf/xslt/example_atom.xsl b/dspace/solr/authority/conf/xslt/example_atom.xsl deleted file mode 100644 index e1c7d5a2af..0000000000 --- a/dspace/solr/authority/conf/xslt/example_atom.xsl +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - Example Solr Atom 1.0 Feed - - This has been formatted by the sample "example_atom.xsl" transform - - use your own XSLT to get a nicer Atom feed. - - - Apache Solr - solr-user@lucene.apache.org - - - - - - tag:localhost,2007:example - - - - - - - - - <xsl:value-of select="str[@name='name']"/> - - tag:localhost,2007: - - - - - - diff --git a/dspace/solr/authority/conf/xslt/example_rss.xsl b/dspace/solr/authority/conf/xslt/example_rss.xsl deleted file mode 100644 index 3e09e654d5..0000000000 --- a/dspace/solr/authority/conf/xslt/example_rss.xsl +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - Example Solr RSS 2.0 Feed - http://localhost:8983/solr - - This has been formatted by the sample "example_rss.xsl" transform - - use your own XSLT to get a nicer RSS feed. - - en-us - http://localhost:8983/solr - - - - - - - - - - - <xsl:value-of select="str[@name='name']"/> - - http://localhost:8983/solr/select?q=id: - - - - - - - http://localhost:8983/solr/select?q=id: - - - - diff --git a/dspace/solr/authority/conf/xslt/luke.xsl b/dspace/solr/authority/conf/xslt/luke.xsl deleted file mode 100644 index 6e9a064d7e..0000000000 --- a/dspace/solr/authority/conf/xslt/luke.xsl +++ /dev/null @@ -1,337 +0,0 @@ - - - - - - - - - Solr Luke Request Handler Response - - - - - - - - - <xsl:value-of select="$title"/> - - - - - -

- -

-
- -
- -

Index Statistics

- -
- -

Field Statistics

- - - -

Document statistics

- - - - -
- - - - - -
- -
- - -
- -
- -
-
-
- - - - - - - - - - - - - - - - - - - - - -
-

- -

- -
- -
-
-
- - -
- - 50 - 800 - 160 - blue - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- background-color: ; width: px; height: px; -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
  • - -
  • -
    -
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/dspace/solr/oai/conf/admin-extra.html b/dspace/solr/oai/conf/admin-extra.html deleted file mode 100644 index aa739da862..0000000000 --- a/dspace/solr/oai/conf/admin-extra.html +++ /dev/null @@ -1,31 +0,0 @@ - - - diff --git a/dspace/solr/oai/conf/elevate.xml b/dspace/solr/oai/conf/elevate.xml deleted file mode 100644 index 7630ebe20f..0000000000 --- a/dspace/solr/oai/conf/elevate.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/dspace/solr/oai/conf/solrconfig.xml b/dspace/solr/oai/conf/solrconfig.xml index 9561ae41c0..c183110c8b 100644 --- a/dspace/solr/oai/conf/solrconfig.xml +++ b/dspace/solr/oai/conf/solrconfig.xml @@ -23,522 +23,112 @@ this file, see http://wiki.apache.org/solr/SolrConfigXml. --> - 8.7.0 + 8.7.0 - ${solr.data.dir:} + ${solr.data.dir:} - + - + - + + - - 32 - 1000 - ${solr.lock.type:native} + + 32 + 1000 + ${solr.lock.type:native} + true + - true - + + + + + 10000 + ${solr.autoCommit.maxTime:10000} + true + - + + ${solr.autoSoftCommit.maxTime:-1} + + - + + + ${solr.max.booleanClauses:1024} - - ${solr.ulog.dir:} - - - - 10000 - ${solr.autoCommit.maxTime:10000} - true - - - - ${solr.autoSoftCommit.maxTime:-1} - - - - - - 1024 - - - - + - + + - true + + - 20 + true + 20 + 200 + false + 2 + - 200 + + + - - - - + + - - - - static firstSearcher warming in solrconfig.xml - - - - - false - - 2 - - - - - - - - - - - - explicit - 10 - item.handle - OR - - - - - - explicit - json - true - item.handle - - - - - - true - json - true - - - - - - explicit - - - velocity - browse - layout - Solritas - - - edismax - - text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 - title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 - - item.handle - 100% - *:* - 10 - *,score - - - text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 - title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 - - text,features,name,sku,id,manu,cat,title,description,keywords,author,resourcename - 3 - - - on - cat - manu_exact - content_type - author_s - ipod - GB - 1 - cat,inStock - after - price - 0 - 600 - 50 - popularity - 0 - 10 - 3 - manufacturedate_dt - NOW/YEAR-10YEARS - NOW - +1YEAR - before - after - - - on - content features title name - html - <b> - </b> - 0 - title - 0 - name - 3 - 200 - content - 750 - - - on - false - 5 - 2 - 5 - true - true - 5 - 3 - - - - spellcheck - - - - - - - + + - application/json - - - - - - true - ignored_ - - - true - links - ignored_ - - - - - - - - - - - - - - - - - - solrpingquery - - - all - - - - - - explicit - true - - - - - - - - - textSpell - - - default - name - ./spellchecker - - - - - - - false - - false - - 1 - - - spellcheck - - - - - - text_general - - - default - item.handle - solr.DirectSolrSpellChecker - internal - 0.5 - 2 - 1 - 5 - 4 - 0.01 - - - - wordbreak - solr.WordBreakSolrSpellChecker - name - true - true - 10 - - - - - - - item.handle - default - wordbreak - on - true - 10 - 5 - 5 - true - true - 10 - 5 - - - spellcheck - - - - - - - - item.handle - true - - - tvComponent - - - - - - default - org.carrot2.clustering.lingo.LingoClusteringAlgorithm - 20 - clustering/carrot2 - ENGLISH - - - stc - org.carrot2.clustering.stc.STCClusteringAlgorithm - - - - - - true - default - true - name - id - features - true - false - - edismax - - text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 - - *:* - 10 - *,score - - - clustering - - - - - - - - true - false - - - terms - - - - - string - elevate.xml - - - - - explicit - item.handle - - - elevator - - - - - - - - 100 + explicit + 10 + item.handle + OR - + - + + - - 70 - - 0.5 - - [-\w ,/\n\"']{20,200} + explicit + json + true + item.handle - + - + + + + - ]]> - ]]> + application/json - + - - - - - - - - - - - - - - ,, - ,, - ,, - ,, - ,]]> - ]]> - - - - - - 10 - .,!? - - - - - - WORD - en - US - - - - - - - text/plain; charset=UTF-8 - - - - - - 5 - - - - *:* - + + text/plain; charset=UTF-8 + diff --git a/dspace/solr/oai/conf/spellings.txt b/dspace/solr/oai/conf/spellings.txt deleted file mode 100644 index 162a044d56..0000000000 --- a/dspace/solr/oai/conf/spellings.txt +++ /dev/null @@ -1,2 +0,0 @@ -pizza -history diff --git a/dspace/solr/oai/conf/xslt/DRI.xsl b/dspace/solr/oai/conf/xslt/DRI.xsl deleted file mode 100644 index f68043c843..0000000000 --- a/dspace/solr/oai/conf/xslt/DRI.xsl +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /metadata/handle/ - - /mets.xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dspace/solr/oai/conf/xslt/example.xsl b/dspace/solr/oai/conf/xslt/example.xsl deleted file mode 100644 index 6832a1d4cb..0000000000 --- a/dspace/solr/oai/conf/xslt/example.xsl +++ /dev/null @@ -1,132 +0,0 @@ - - - - - - - - - - - - - - - <xsl:value-of select="$title"/> - - - -

-
- This has been formatted by the sample "example.xsl" transform - - use your own XSLT to get a nicer page -
- - - -
- - - -
- - - - -
-
-
- - - - - - - - - - - - - - javascript:toggle("");? -
- - exp - - - - - -
- - -
- - - - - - - -
    - -
  • -
    -
- - -
- - - - - - - - - - - - - - - - - - - - -
diff --git a/dspace/solr/oai/conf/xslt/example_atom.xsl b/dspace/solr/oai/conf/xslt/example_atom.xsl deleted file mode 100644 index e1c7d5a2af..0000000000 --- a/dspace/solr/oai/conf/xslt/example_atom.xsl +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - Example Solr Atom 1.0 Feed - - This has been formatted by the sample "example_atom.xsl" transform - - use your own XSLT to get a nicer Atom feed. - - - Apache Solr - solr-user@lucene.apache.org - - - - - - tag:localhost,2007:example - - - - - - - - - <xsl:value-of select="str[@name='name']"/> - - tag:localhost,2007: - - - - - - diff --git a/dspace/solr/oai/conf/xslt/example_rss.xsl b/dspace/solr/oai/conf/xslt/example_rss.xsl deleted file mode 100644 index 3e09e654d5..0000000000 --- a/dspace/solr/oai/conf/xslt/example_rss.xsl +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - Example Solr RSS 2.0 Feed - http://localhost:8983/solr - - This has been formatted by the sample "example_rss.xsl" transform - - use your own XSLT to get a nicer RSS feed. - - en-us - http://localhost:8983/solr - - - - - - - - - - - <xsl:value-of select="str[@name='name']"/> - - http://localhost:8983/solr/select?q=id: - - - - - - - http://localhost:8983/solr/select?q=id: - - - - diff --git a/dspace/solr/oai/conf/xslt/luke.xsl b/dspace/solr/oai/conf/xslt/luke.xsl deleted file mode 100644 index 6e9a064d7e..0000000000 --- a/dspace/solr/oai/conf/xslt/luke.xsl +++ /dev/null @@ -1,337 +0,0 @@ - - - - - - - - - Solr Luke Request Handler Response - - - - - - - - - <xsl:value-of select="$title"/> - - - - - -

- -

-
- -

Index Statistics

- -
- -

Field Statistics

- - - -

Document statistics

- - - - -
- - - - - -
- -
- - -
- -
- -
-
-
- - - - - - - - - - - - - - - - - - - - - -
-

- -

- -
- -
-
-
- - -
- - 50 - 800 - 160 - blue - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- background-color: ; width: px; height: px; -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
  • - -
  • -
    -
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dspace/solr/search/conf/admin-extra.html b/dspace/solr/search/conf/admin-extra.html deleted file mode 100644 index aa739da862..0000000000 --- a/dspace/solr/search/conf/admin-extra.html +++ /dev/null @@ -1,31 +0,0 @@ - - - diff --git a/dspace/solr/search/conf/elevate.xml b/dspace/solr/search/conf/elevate.xml deleted file mode 100644 index 7630ebe20f..0000000000 --- a/dspace/solr/search/conf/elevate.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/dspace/solr/search/conf/solrconfig.xml b/dspace/solr/search/conf/solrconfig.xml index 669b76db4c..2026d842d6 100644 --- a/dspace/solr/search/conf/solrconfig.xml +++ b/dspace/solr/search/conf/solrconfig.xml @@ -23,530 +23,149 @@ this file, see http://wiki.apache.org/solr/SolrConfigXml. --> - 8.7.0 + 8.7.0 - - - - - + + + + + - ${solr.data.dir:} + ${solr.data.dir:} - + - + - + + - - 100 - 1000 + + 100 + 1000 + ${solr.lock.type:native} + true + - ${solr.lock.type:native} + + + + + 10000 + ${solr.autoCommit.maxTime:10000} + true + - true - + + ${solr.autoSoftCommit.maxTime:-1} + + - + + + ${solr.max.booleanClauses:1024} - - - - ${solr.ulog.dir:} - - - - 10000 - ${solr.autoCommit.maxTime:10000} - true - - - - ${solr.autoSoftCommit.maxTime:-1} - - - - - - ${solr.max.booleanClauses:1024} - - - - + - + + - true + + - 20 + true + 20 + 200 + false + 2 + - 200 + + + - - - + + - - - - static firstSearcher warming in solrconfig.xml - - - - - false - - 2 - - - - - - - - - - - - explicit - 10 - search_text - AND - - - spellcheck - - - - - - - explicit - json - true - search_text - - - - - - true - json - true - - - - - - explicit - - - velocity - browse - layout - Solritas - - - edismax - - text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 - title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 - - search_text - 100% - *:* - 10 - *,score - - - text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 - title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 - - search_text,features,name,sku,id,manu,cat,title,description,keywords,author,resourcename - 3 - - - on - cat - manu_exact - content_type - author_s - ipod - GB - 1 - cat,inStock - after - price - 0 - 600 - 50 - popularity - 0 - 10 - 3 - manufacturedate_dt - NOW/YEAR-10YEARS - NOW - +1YEAR - before - after - - - on - content features title name - html - <b> - </b> - 0 - title - 0 - name - 3 - 200 - content - 750 - - - on - false - 5 - 2 - 5 - true - true - 5 - 3 - - - - spellcheck - - - - - - + + - application/json - - - - - - ignored_ - true - - - - - - - - - - - - - - - - - - solrpingquery - - - all - - - - - - explicit - true - - - - - - - - - textSpell - - - solr.IndexBasedSpellChecker - default - a_spell - ./spellchecker - true - false - - - - - - false - false - 1 - - - spellcheck - - - - - - text_general - - - default - search_text - solr.DirectSolrSpellChecker - internal - 0.5 - 2 - 1 - 5 - 4 - 0.01 - - - - wordbreak - solr.WordBreakSolrSpellChecker - name - true - true - 10 - - - - - - search_text - default - wordbreak - on - true - 10 - 5 - 5 - true - true - 10 - 5 - - - spellcheck - - - - - - - - search_text - true - - - tvComponent - - - - - - default - org.carrot2.clustering.lingo.LingoClusteringAlgorithm - 20 - clustering/carrot2 - ENGLISH - - - stc - org.carrot2.clustering.stc.STCClusteringAlgorithm - - - - - - true - default - true - name - id - features - true - false - - edismax - - text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 - - *:* - 10 - *,score - - - clustering - - - - - - - - true - false - - - terms - - - - - - string - elevate.xml - - - - - explicit - search_text - - - elevator - - - - - - - - 100 + explicit + 10 + search_text + AND - + + spellcheck + + - + + - - 70 - - 0.5 - - [-\w ,/\n\"']{20,200} + explicit + json + true + search_text - + - + + + + + + application/json + + + + + + textSpell + + + solr.IndexBasedSpellChecker + default + a_spell + ./spellchecker + true + false + + + + - ]]> - ]]> + false + false + 1 - + + spellcheck + + - - - - - - - - - - - - - - ,, - ,, - ,, - ,, - ,]]> - ]]> - - - - - - 10 - .,!? - - - - - - WORD - en - US - - - - - - - text/plain; charset=UTF-8 - - - - - - 5 - - - - - *:* - + + text/plain; charset=UTF-8 + diff --git a/dspace/solr/search/conf/spellings.txt b/dspace/solr/search/conf/spellings.txt deleted file mode 100644 index 162a044d56..0000000000 --- a/dspace/solr/search/conf/spellings.txt +++ /dev/null @@ -1,2 +0,0 @@ -pizza -history diff --git a/dspace/solr/search/conf/xslt/DRI.xsl b/dspace/solr/search/conf/xslt/DRI.xsl deleted file mode 100644 index f68043c843..0000000000 --- a/dspace/solr/search/conf/xslt/DRI.xsl +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /metadata/handle/ - - /mets.xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dspace/solr/search/conf/xslt/example.xsl b/dspace/solr/search/conf/xslt/example.xsl deleted file mode 100644 index 6832a1d4cb..0000000000 --- a/dspace/solr/search/conf/xslt/example.xsl +++ /dev/null @@ -1,132 +0,0 @@ - - - - - - - - - - - - - - - <xsl:value-of select="$title"/> - - - -

-
- This has been formatted by the sample "example.xsl" transform - - use your own XSLT to get a nicer page -
- - - -
- - - -
- - - - -
-
-
- - - - - - - - - - - - - - javascript:toggle("");? -
- - exp - - - - - -
- - -
- - - - - - - -
    - -
  • -
    -
- - -
- - - - - - - - - - - - - - - - - - - - -
diff --git a/dspace/solr/search/conf/xslt/example_atom.xsl b/dspace/solr/search/conf/xslt/example_atom.xsl deleted file mode 100644 index e1c7d5a2af..0000000000 --- a/dspace/solr/search/conf/xslt/example_atom.xsl +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - Example Solr Atom 1.0 Feed - - This has been formatted by the sample "example_atom.xsl" transform - - use your own XSLT to get a nicer Atom feed. - - - Apache Solr - solr-user@lucene.apache.org - - - - - - tag:localhost,2007:example - - - - - - - - - <xsl:value-of select="str[@name='name']"/> - - tag:localhost,2007: - - - - - - diff --git a/dspace/solr/search/conf/xslt/example_rss.xsl b/dspace/solr/search/conf/xslt/example_rss.xsl deleted file mode 100644 index 3e09e654d5..0000000000 --- a/dspace/solr/search/conf/xslt/example_rss.xsl +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - Example Solr RSS 2.0 Feed - http://localhost:8983/solr - - This has been formatted by the sample "example_rss.xsl" transform - - use your own XSLT to get a nicer RSS feed. - - en-us - http://localhost:8983/solr - - - - - - - - - - - <xsl:value-of select="str[@name='name']"/> - - http://localhost:8983/solr/select?q=id: - - - - - - - http://localhost:8983/solr/select?q=id: - - - - diff --git a/dspace/solr/search/conf/xslt/luke.xsl b/dspace/solr/search/conf/xslt/luke.xsl deleted file mode 100644 index 6e9a064d7e..0000000000 --- a/dspace/solr/search/conf/xslt/luke.xsl +++ /dev/null @@ -1,337 +0,0 @@ - - - - - - - - - Solr Luke Request Handler Response - - - - - - - - - <xsl:value-of select="$title"/> - - - - - -

- -

-
- -

Index Statistics

- -
- -

Field Statistics

- - - -

Document statistics

- - - - -
- - - - - -
- -
- - -
- -
- -
-
-
- - - - - - - - - - - - - - - - - - - - - -
-

- -

- -
- -
-
-
- - -
- - 50 - 800 - 160 - blue - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- background-color: ; width: px; height: px; -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
  • - -
  • -
    -
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dspace/solr/statistics/conf/admin-extra.html b/dspace/solr/statistics/conf/admin-extra.html deleted file mode 100644 index aa739da862..0000000000 --- a/dspace/solr/statistics/conf/admin-extra.html +++ /dev/null @@ -1,31 +0,0 @@ - - - diff --git a/dspace/solr/statistics/conf/elevate.xml b/dspace/solr/statistics/conf/elevate.xml deleted file mode 100644 index 7630ebe20f..0000000000 --- a/dspace/solr/statistics/conf/elevate.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/dspace/solr/statistics/conf/scripts.conf b/dspace/solr/statistics/conf/scripts.conf deleted file mode 100644 index f58b262ae0..0000000000 --- a/dspace/solr/statistics/conf/scripts.conf +++ /dev/null @@ -1,24 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -user= -solr_hostname=localhost -solr_port=8983 -rsyncd_port=18983 -data_dir= -webapp_name=solr -master_host= -master_data_dir= -master_status_dir= diff --git a/dspace/solr/statistics/conf/solrconfig.xml b/dspace/solr/statistics/conf/solrconfig.xml index f0b8bcb6fb..ee7b9c42c0 100644 --- a/dspace/solr/statistics/conf/solrconfig.xml +++ b/dspace/solr/statistics/conf/solrconfig.xml @@ -23,532 +23,126 @@ this file, see http://wiki.apache.org/solr/SolrConfigXml. --> - 8.7.0 + 8.7.0 - ${solr.data.dir:} + ${solr.data.dir:} - + - + - + + - - 32 - 1000 - ${solr.lock.type:native} - true - + + 32 + 1000 + ${solr.lock.type:native} + true + - + + + + + 10000 + ${solr.autoCommit.maxTime:900000} + true + - + + ${solr.autoSoftCommit.maxTime:-1} + + - - ${solr.ulog.dir:} - + + + ${solr.max.booleanClauses:1024} - - 10000 - ${solr.autoCommit.maxTime:900000} - true - - - - ${solr.autoSoftCommit.maxTime:-1} - - - - - - 1024 - - - - + - + + - true + + - 20 + true + 20 + 200 + false + 2 + - 200 + + + - - - - + + - - - - static firstSearcher warming in solrconfig.xml + + + + explicit + 10 + id + AND - - - - false - - 2 - - - - - - - - - - - - explicit - 10 - id - AND - - - - explicit - json - true - id - - - - - - true - json - true - - - - - - explicit - - - velocity - browse - layout - Solritas - - - edismax - - text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 - title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 - - id - 100% - *:* - 10 - *,score - - - text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 - title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 - - text,features,name,sku,id,manu,cat,title,description,keywords,author,resourcename - 3 - - - on - cat - manu_exact - content_type - author_s - ipod - GB - 1 - cat,inStock - after - price - 0 - 600 - 50 - popularity - 0 - 10 - 3 - manufacturedate_dt - NOW/YEAR-10YEARS - NOW - +1YEAR - before - after - - - on - content features title name - html - <b> - </b> - 0 - title - 0 - name - 3 - 200 - content - 750 - - - on - false - 5 - 2 - 5 - true - true - 5 - 3 - - - - spellcheck - - - - - - - uuid - - - - + + - application/json - uuid - - - - - - true - ignored_ - - - true - links - ignored_ - - - - - - - - - - - - - - - - - - solrpingquery - - - all - - - - - - explicit - true - - - - - - - - textSpell - - - default - name - ./spellchecker - - - - - - - - false - - false - - 1 - - - spellcheck - - - - - - text_general - - - default - id - solr.DirectSolrSpellChecker - internal - 0.5 - 2 - 1 - 5 - 4 - 0.01 - - - - wordbreak - solr.WordBreakSolrSpellChecker - name - true - true - 10 - - - - - - - id - default - wordbreak - on - true - 10 - 5 - 5 - true - true - 10 - 5 - - - spellcheck - - - - - - - - id - true - - - tvComponent - - - - - - default - org.carrot2.clustering.lingo.LingoClusteringAlgorithm - 20 - clustering/carrot2 - ENGLISH - - - stc - org.carrot2.clustering.stc.STCClusteringAlgorithm - - - - - - true - default - true - name - id - features - true - false - - edismax - - text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 - - *:* - 10 - *,score - - - clustering - - - - - - - - true - false - - - terms - - - - - - string - elevate.xml - - - - - explicit - id - - - elevator - - - - - - - - 100 + explicit + json + true + id - + - + + + - 70 - 0.5 - [-\w ,/\n\"']{20,200} + uuid - + - + - ]]> - ]]> + application/json + uuid - + - + + + + uid + + + - - - - - - - - - - - - ,, - ,, - ,, - ,, - ,]]> - ]]> - - - - - - 10 - .,!? - - - - - - WORD - en - US - - - - - - - - - uid - - - - - - text/plain; charset=UTF-8 - - - - - - 5 - - - - *:* - + + text/plain; charset=UTF-8 + diff --git a/dspace/solr/statistics/conf/spellings.txt b/dspace/solr/statistics/conf/spellings.txt deleted file mode 100644 index d7ede6f561..0000000000 --- a/dspace/solr/statistics/conf/spellings.txt +++ /dev/null @@ -1,2 +0,0 @@ -pizza -history \ No newline at end of file diff --git a/dspace/solr/statistics/conf/xslt/example.xsl b/dspace/solr/statistics/conf/xslt/example.xsl deleted file mode 100644 index 6832a1d4cb..0000000000 --- a/dspace/solr/statistics/conf/xslt/example.xsl +++ /dev/null @@ -1,132 +0,0 @@ - - - - - - - - - - - - - - - <xsl:value-of select="$title"/> - - - -

-
- This has been formatted by the sample "example.xsl" transform - - use your own XSLT to get a nicer page -
- - - -
- - - -
- - - - -
-
-
- - - - - - - - - - - - - - javascript:toggle("");? -
- - exp - - - - - -
- - -
- - - - - - - -
    - -
  • -
    -
- - -
- - - - - - - - - - - - - - - - - - - - -
diff --git a/dspace/solr/statistics/conf/xslt/example_atom.xsl b/dspace/solr/statistics/conf/xslt/example_atom.xsl deleted file mode 100644 index e1c7d5a2af..0000000000 --- a/dspace/solr/statistics/conf/xslt/example_atom.xsl +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - Example Solr Atom 1.0 Feed - - This has been formatted by the sample "example_atom.xsl" transform - - use your own XSLT to get a nicer Atom feed. - - - Apache Solr - solr-user@lucene.apache.org - - - - - - tag:localhost,2007:example - - - - - - - - - <xsl:value-of select="str[@name='name']"/> - - tag:localhost,2007: - - - - - - diff --git a/dspace/solr/statistics/conf/xslt/example_rss.xsl b/dspace/solr/statistics/conf/xslt/example_rss.xsl deleted file mode 100644 index 3e09e654d5..0000000000 --- a/dspace/solr/statistics/conf/xslt/example_rss.xsl +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - Example Solr RSS 2.0 Feed - http://localhost:8983/solr - - This has been formatted by the sample "example_rss.xsl" transform - - use your own XSLT to get a nicer RSS feed. - - en-us - http://localhost:8983/solr - - - - - - - - - - - <xsl:value-of select="str[@name='name']"/> - - http://localhost:8983/solr/select?q=id: - - - - - - - http://localhost:8983/solr/select?q=id: - - - - diff --git a/dspace/solr/statistics/conf/xslt/luke.xsl b/dspace/solr/statistics/conf/xslt/luke.xsl deleted file mode 100644 index 6e9a064d7e..0000000000 --- a/dspace/solr/statistics/conf/xslt/luke.xsl +++ /dev/null @@ -1,337 +0,0 @@ - - - - - - - - - Solr Luke Request Handler Response - - - - - - - - - <xsl:value-of select="$title"/> - - - - - -

- -

-
- -

Index Statistics

- -
- -

Field Statistics

- - - -

Document statistics

- - - - - - - - - - -
- -
- - -
- -
- -
-
-
- - - - - - - - - - - - - - - - - - - - - -
-

- -

- -
- -
-
-
- - -
- - 50 - 800 - 160 - blue - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- background-color: ; width: px; height: px; -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
  • - -
  • -
    -
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 575994fab1ffc3ac33efcea4eec5654f0473c11c Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 26 Feb 2021 10:03:32 -0600 Subject: [PATCH 106/179] Apply prior feedback on further config cleanup --- dspace/solr/authority/conf/solrconfig.xml | 3 ++- dspace/solr/oai/conf/solrconfig.xml | 7 ++----- dspace/solr/search/conf/solrconfig.xml | 7 ++----- dspace/solr/statistics/conf/solrconfig.xml | 7 ++----- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/dspace/solr/authority/conf/solrconfig.xml b/dspace/solr/authority/conf/solrconfig.xml index ba75b266b7..e6c9fc4f88 100644 --- a/dspace/solr/authority/conf/solrconfig.xml +++ b/dspace/solr/authority/conf/solrconfig.xml @@ -36,7 +36,8 @@ 32 1000 ${solr.lock.type:native} - true + + false diff --git a/dspace/solr/oai/conf/solrconfig.xml b/dspace/solr/oai/conf/solrconfig.xml index c183110c8b..ae0bd321ec 100644 --- a/dspace/solr/oai/conf/solrconfig.xml +++ b/dspace/solr/oai/conf/solrconfig.xml @@ -39,7 +39,8 @@ 32 1000 ${solr.lock.type:native} - true + + false @@ -127,8 +128,4 @@ application/json - - - text/plain; charset=UTF-8 - diff --git a/dspace/solr/search/conf/solrconfig.xml b/dspace/solr/search/conf/solrconfig.xml index 2026d842d6..b3fa666bae 100644 --- a/dspace/solr/search/conf/solrconfig.xml +++ b/dspace/solr/search/conf/solrconfig.xml @@ -48,7 +48,8 @@ 100 1000 ${solr.lock.type:native} - true + + false @@ -164,8 +165,4 @@ spellcheck - - - text/plain; charset=UTF-8 - diff --git a/dspace/solr/statistics/conf/solrconfig.xml b/dspace/solr/statistics/conf/solrconfig.xml index ee7b9c42c0..8b2db9c22f 100644 --- a/dspace/solr/statistics/conf/solrconfig.xml +++ b/dspace/solr/statistics/conf/solrconfig.xml @@ -39,7 +39,8 @@ 32 1000 ${solr.lock.type:native} - true + + false @@ -141,8 +142,4 @@ - - - text/plain; charset=UTF-8 - From 7b9e3d70bb437422d09583b7d9bd26cd9db87769 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 26 Feb 2021 12:29:52 -0600 Subject: [PATCH 107/179] Upgrade to Solr 8.8.1 (from 8.7) --- docker-compose.yml | 2 +- dspace/solr/authority/conf/solrconfig.xml | 2 +- dspace/solr/oai/conf/solrconfig.xml | 2 +- dspace/solr/search/conf/solrconfig.xml | 2 +- dspace/solr/statistics/conf/solrconfig.xml | 2 +- pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index cb96dfad77..db87402413 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -54,7 +54,7 @@ services: dspacesolr: container_name: dspacesolr # Uses official Solr image at https://hub.docker.com/_/solr/ - image: solr:8.7 + image: solr:8.8 networks: dspacenet: ports: diff --git a/dspace/solr/authority/conf/solrconfig.xml b/dspace/solr/authority/conf/solrconfig.xml index e6c9fc4f88..373cbb661c 100644 --- a/dspace/solr/authority/conf/solrconfig.xml +++ b/dspace/solr/authority/conf/solrconfig.xml @@ -24,7 +24,7 @@ --> - 8.7.0 + 8.8.1 diff --git a/dspace/solr/oai/conf/solrconfig.xml b/dspace/solr/oai/conf/solrconfig.xml index ae0bd321ec..bb7e18e508 100644 --- a/dspace/solr/oai/conf/solrconfig.xml +++ b/dspace/solr/oai/conf/solrconfig.xml @@ -23,7 +23,7 @@ this file, see http://wiki.apache.org/solr/SolrConfigXml. --> - 8.7.0 + 8.8.1 ${solr.data.dir:} diff --git a/dspace/solr/search/conf/solrconfig.xml b/dspace/solr/search/conf/solrconfig.xml index b3fa666bae..07b20553ec 100644 --- a/dspace/solr/search/conf/solrconfig.xml +++ b/dspace/solr/search/conf/solrconfig.xml @@ -23,7 +23,7 @@ this file, see http://wiki.apache.org/solr/SolrConfigXml. --> - 8.7.0 + 8.8.1 - 8.7.0 + 8.8.1 ${solr.data.dir:} diff --git a/pom.xml b/pom.xml index c92e614a2d..ab9c4d874b 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ 5.4.10.Final 6.0.18.Final 42.2.9 - 8.7.0 + 8.8.1 1.2.22 2.3.4 From 215d3c032533a6e3423efba93a5bbe9d89681e22 Mon Sep 17 00:00:00 2001 From: j4bbi Date: Sun, 28 Feb 2021 00:59:56 +0000 Subject: [PATCH 108/179] Get rid of Java7, upgrade DBCP2 dependency --- pom.xml | 44 +++++++------------------------------------- 1 file changed, 7 insertions(+), 37 deletions(-) diff --git a/pom.xml b/pom.xml index 74574d1084..5b070dfdb6 100644 --- a/pom.xml +++ b/pom.xml @@ -712,42 +712,6 @@ - - - - postgresql-jdbc-default - - [1.8,) - - - - - org.postgresql - postgresql - ${postgresql.driver.version} - - - - - - - postgresql-jdbc-jre7 - - [1.7,1.8) - - - - - org.postgresql - postgresql - ${postgresql.driver.version}.jre7 - - - - - + + org.postgresql + postgresql + ${postgresql.driver.version} + + @@ -1336,7 +1306,7 @@ org.apache.commons commons-dbcp2 - 2.1.1 + 2.8.0 commons-fileupload From 7186d07e2b6077f8f86c390c23b26085cd90bc00 Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Mon, 1 Mar 2021 17:40:43 +0100 Subject: [PATCH 109/179] 77228: Implement MetadataAuthorityService#clearCache --- .../content/authority/MetadataAuthorityServiceImpl.java | 9 +++++++++ .../authority/service/MetadataAuthorityService.java | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/content/authority/MetadataAuthorityServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/authority/MetadataAuthorityServiceImpl.java index 932d0d2c4c..fa2abd0bc9 100644 --- a/dspace-api/src/main/java/org/dspace/content/authority/MetadataAuthorityServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/authority/MetadataAuthorityServiceImpl.java @@ -222,4 +222,13 @@ public class MetadataAuthorityServiceImpl implements MetadataAuthorityService { } return copy; } + + @Override + public void clearCache() { + controlled.clear(); + isAuthorityRequired.clear(); + minConfidence.clear(); + + isAuthorityRequired = null; + } } diff --git a/dspace-api/src/main/java/org/dspace/content/authority/service/MetadataAuthorityService.java b/dspace-api/src/main/java/org/dspace/content/authority/service/MetadataAuthorityService.java index 3cf16b35c9..2ba6791de5 100644 --- a/dspace-api/src/main/java/org/dspace/content/authority/service/MetadataAuthorityService.java +++ b/dspace-api/src/main/java/org/dspace/content/authority/service/MetadataAuthorityService.java @@ -112,4 +112,9 @@ public interface MetadataAuthorityService { * @return the list of metadata field with authority control */ public List getAuthorityMetadata(); + + /** + * This method has been created to have a way of clearing the cache kept inside the service + */ + public void clearCache(); } From b41ebf9c604e5af78fa9a854c662d48a08b7d32c Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Mon, 1 Mar 2021 17:42:20 +0100 Subject: [PATCH 110/179] 77228: Overload withSubject: authority & confidence parameters --- .../builder/AbstractDSpaceObjectBuilder.java | 15 +++++++++++++++ .../test/java/org/dspace/builder/ItemBuilder.java | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/dspace-api/src/test/java/org/dspace/builder/AbstractDSpaceObjectBuilder.java b/dspace-api/src/test/java/org/dspace/builder/AbstractDSpaceObjectBuilder.java index 69cfd0e136..a2a8aa9d42 100644 --- a/dspace-api/src/test/java/org/dspace/builder/AbstractDSpaceObjectBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/AbstractDSpaceObjectBuilder.java @@ -83,6 +83,21 @@ public abstract class AbstractDSpaceObjectBuilder return (B) this; } + protected > B addMetadataValue(final T dso, final String schema, + final String element, + final String qualifier, + final String language, + final String value, + final String authority, + final int confidence) { + try { + getService().addMetadata(context, dso, schema, element, qualifier, language, value, authority, confidence); + } catch (Exception e) { + return handleException(e); + } + return (B) this; + } + protected > B setMetadataSingleValue(final T dso, final String schema, final String element, final String qualifier, diff --git a/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java b/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java index 604043a4c0..c53fb2d9f3 100644 --- a/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java @@ -86,6 +86,10 @@ public class ItemBuilder extends AbstractDSpaceObjectBuilder { return addMetadataValue(item, MetadataSchemaEnum.DC.getName(), "subject", null, subject); } + public ItemBuilder withSubject(final String subject, final String authority, final int confidence) { + return addMetadataValue(item, MetadataSchemaEnum.DC.getName(), "subject", null, null, subject, authority, confidence); + } + public ItemBuilder withRelationshipType(final String relationshipType) { return addMetadataValue(item, "relationship", "type", null, relationshipType); } From b089b179b7f7e9f0587308d0cf85942050154c1e Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Mon, 1 Mar 2021 17:43:33 +0100 Subject: [PATCH 111/179] 77228: BrowseEntryResourceMatcher#matchBrowseEntry with authority value --- .../app/rest/matcher/BrowseEntryResourceMatcher.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/BrowseEntryResourceMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/BrowseEntryResourceMatcher.java index e21f9ba8ae..614b03601c 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/BrowseEntryResourceMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/BrowseEntryResourceMatcher.java @@ -35,6 +35,17 @@ public class BrowseEntryResourceMatcher { ); } + public static Matcher matchBrowseEntry(String entryValue, String authorityValue, int expectedCount) { + return allOf( + //Check core metadata (the JSON Path expression evaluates to a collection so we have to use contains) + hasJsonPath("$.value", is(entryValue)), + hasJsonPath("$.authority", is(authorityValue)), + hasJsonPath("$.count", is(expectedCount)), + //Check links + matchItemLinks() + ); + } + public static Matcher matchItemLinks() { return allOf( hasJsonPath("$._links.items.href", startsWith(REST_SERVER_URL)) From c5916b136c529dea9124cedb07a8ae3e67cacd0a Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Mon, 1 Mar 2021 17:45:25 +0100 Subject: [PATCH 112/179] 77228: Add IT for browse by subject with authority values Doesn't pass ~ no Solr results @ BroweEntryLinkRepository#listBrowseEntries --- .../app/rest/BrowsesResourceControllerIT.java | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java index 0cf282b1ab..7bec3f3041 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java @@ -31,9 +31,12 @@ import org.dspace.builder.ItemBuilder; import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.Item; +import org.dspace.content.authority.service.MetadataAuthorityService; import org.dspace.eperson.Group; +import org.dspace.services.ConfigurationService; import org.hamcrest.Matchers; import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.web.servlet.result.MockMvcResultHandlers; /** @@ -44,6 +47,11 @@ import org.springframework.test.web.servlet.result.MockMvcResultHandlers; * @author Tom Desair (tom dot desair at atmire dot com) */ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTest { + @Autowired + ConfigurationService configurationService; + + @Autowired + MetadataAuthorityService metadataAuthorityService; @Test public void findAll() throws Exception { @@ -215,6 +223,100 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe ))); } + @Test + public void findBrowseBySubjectEntriesWithAuthority() throws Exception { + configurationService.setProperty("choices.plugin.dc.subject", + "SolrSubjectAuthority"); + configurationService.setProperty("authority.controlled.dc.subject", + "true"); + + metadataAuthorityService.clearCache(); + + context.turnOffAuthorisationSystem(); + + //** GIVEN ** + //1. A community-collection structure with one parent community with sub-community and two collections. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build(); + Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build(); + + //2. Three public items that are readable by Anonymous with different subjects + Item publicItem1 = ItemBuilder.createItem(context, col1) + .withTitle("Public item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withSubject("ExtraEntry", "authority_1", 600) + .build(); + + Item publicItem2 = ItemBuilder.createItem(context, col2) + .withTitle("Public item 2") + .withIssueDate("2016-02-13") + .withAuthor("Smith, Maria").withAuthor("Doe, Jane") + .withSubject("TestingForMore", "authority_2", 600) + .withSubject("ExtraEntry", "authority_1", 600) + .build(); + + Item publicItem3 = ItemBuilder.createItem(context, col2) + .withTitle("Public item 2") + .withIssueDate("2016-02-13") + .withAuthor("Smith, Maria").withAuthor("Doe, Jane") + .withSubject("AnotherTest", "authority_3", 600) + .withSubject("TestingForMore", "authority_2", 600) + .withSubject("ExtraEntry", "authority_1", 600) + .build(); + + context.restoreAuthSystemState(); + + //** WHEN ** + //An anonymous user browses this endpoint to find which subjects are currently in the repository + getClient().perform(get("/api/discover/browses/subject/entries") + .param("projection", "full")) + + //** THEN ** + //The status has to be 200 + .andExpect(status().isOk()) + + //We expect the content type to be "application/hal+json;charset=UTF-8" + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.page.size", is(20))) + //Check that there are indeed 3 different subjects + .andExpect(jsonPath("$.page.totalElements", is(3))) + //Check the embedded resources and that they're sorted alphabetically + //Check that the subject matches as expected + //Verify that they're sorted alphabetically + .andExpect(jsonPath("$._embedded.entries", + contains(BrowseEntryResourceMatcher.matchBrowseEntry("AnotherTest", "authority_3", 1), + BrowseEntryResourceMatcher.matchBrowseEntry("ExtraEntry", "authority_1", 3), + BrowseEntryResourceMatcher.matchBrowseEntry("TestingForMore", "authority_2", 2) + ))); + + getClient().perform(get("/api/discover/browses/subject/entries") + .param("sort", "value,desc")) + + //** THEN ** + //The status has to be 200 + .andExpect(status().isOk()) + .andDo(MockMvcResultHandlers.print()) + //We expect the content type to be "application/hal+json;charset=UTF-8" + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.page.size", is(20))) + //Check that there are indeed 3 different subjects + .andExpect(jsonPath("$.page.totalElements", is(3))) + //Check the embedded resources and that they're sorted alphabetically + //Check that the subject matches as expected + //Verify that they're sorted alphabetically + .andExpect(jsonPath("$._embedded.entries", + contains(BrowseEntryResourceMatcher.matchBrowseEntry("AnotherTest", "authority_3", 1), + BrowseEntryResourceMatcher.matchBrowseEntry("ExtraEntry", "authority_1", 3), + BrowseEntryResourceMatcher.matchBrowseEntry("TestingForMore", "authority_2", 2) + ))); + } + @Test public void findBrowseBySubjectItems() throws Exception { context.turnOffAuthorisationSystem(); From 52f17c3f1205549ab8ba030a79e609383cb7d06c Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Mon, 1 Mar 2021 17:46:12 +0100 Subject: [PATCH 113/179] 77228: Match facet value by subject --- .../org/dspace/app/rest/matcher/FacetValueMatcher.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java index 213d93de09..b881e5974f 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java @@ -28,6 +28,16 @@ public class FacetValueMatcher { ); } + public static Matcher entrySubject(String label, int count) { + return allOf( + hasJsonPath("$.label", is(label)), + hasJsonPath("$.type", is("discover")), + hasJsonPath("$.count", is(count)), + hasJsonPath("$._links.search.href", containsString("api/discover/search/objects")), + hasJsonPath("$._links.search.href", containsString("f.subject=" + label + ",equals")) + ); + } + public static Matcher entryDateIssued() { return allOf( hasJsonPath("$.label", Matchers.notNullValue()), From a7db90c13aca0bf380c07eb73c34ea1455d5c670 Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Mon, 1 Mar 2021 17:48:24 +0100 Subject: [PATCH 114/179] 77228: Add IT for subject facet with authority value Doesn't pass ~ no Solr results @ DiscoveryRestController#getFacetValues --- .../app/rest/DiscoveryRestControllerIT.java | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java index 5d97062d36..40e91dff34 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java @@ -50,16 +50,24 @@ import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; +import org.dspace.content.authority.service.MetadataAuthorityService; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; +import org.dspace.services.ConfigurationService; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.hamcrest.Matchers; import org.junit.Ignore; import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest { + @Autowired + ConfigurationService configurationService; + + @Autowired + MetadataAuthorityService metadataAuthorityService; @Test @@ -178,6 +186,94 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest ; } + @Test + public void discoverFacetsAuthorWithAuthorityWithSizeParameter() throws Exception { + configurationService.setProperty("choices.plugin.dc.subject", + "SolrSubjectAuthority"); + configurationService.setProperty("authority.controlled.dc.subject", + "true"); + + metadataAuthorityService.clearCache(); + + //Turn off the authorization system, otherwise we can't make the objects + context.turnOffAuthorisationSystem(); + + //** GIVEN ** + //1. A community-collection structure with one parent community with sub-community and two collections. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build(); + Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build(); + + //2. Three public items that are readable by Anonymous with different subjects and authors + Item publicItem1 = ItemBuilder.createItem(context, col1) + .withTitle("Public item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withAuthor("Doe, John") + .withSubject("ExtraEntry", "authority_1", 600) + .build(); + + Item publicItem2 = ItemBuilder.createItem(context, col2) + .withTitle("Public item 2") + .withIssueDate("2016-02-13") + .withAuthor("Smith, Maria") + .withAuthor("Doe, Jane") + .withSubject("TestingForMore", "authority_2", 600) + .withSubject("ExtraEntry", "authority_1", 600) + .build(); + + Item publicItem3 = ItemBuilder.createItem(context, col2) + .withTitle("Public item 2") + .withIssueDate("2016-02-13") + .withAuthor("Smith, Maria") + .withAuthor("Doe, Jane") + .withAuthor("test, test") + .withAuthor("test2, test2") + .withAuthor("Maybe, Maybe") + .withSubject("AnotherTest", "authority_3", 600) + .withSubject("TestingForMore", "authority_2", 600) + .withSubject("ExtraEntry", "authority_1", 600) + .build(); + + context.restoreAuthSystemState(); + + //** WHEN ** + //An anonymous user browses this endpoint to find the objects in the system and enters a size of 2 + getClient().perform(get("/api/discover/facets/subject") + .param("size", "2")) + + //** THEN ** + //The status has to be 200 OK + .andExpect(status().isOk()) + //The type needs to be 'discover' + .andExpect(jsonPath("$.type", is("discover"))) + //The name of the facet needs to be seubject, because that's what we called + .andExpect(jsonPath("$.name", is("subject"))) + //Because we've constructed such a structure so that we have more than 2 (size) subjects, there + // needs to be a next link + .andExpect(jsonPath("$._links.next.href", containsString("api/discover/facets/subject?page"))) + //There always needs to be a self link + .andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/subject"))) + //Because there are more subjects than is represented (because of the size param), hasMore has to + // be true + //The page object needs to be present and just like specified in the matcher + .andExpect(jsonPath("$.page", + is(PageMatcher.pageEntry(0, 2)))) + //These subjecs need to be in the response because it's sorted on how many times the author comes + // up in different items + //These subjects are the most used ones. Only two show up because of the size. + .andExpect(jsonPath("$._embedded.values", containsInAnyOrder( + FacetValueMatcher.entrySubject("ExtraEntry", 3), + FacetValueMatcher.entrySubject("TestingForMore", 2) + ))) + ; + } + @Test public void discoverFacetsAuthorTestWithPrefix() throws Exception { //Turn off the authorization system, otherwise we can't make the objects From f2527d9f21dfc026a521abf797e560be2b199709 Mon Sep 17 00:00:00 2001 From: Peter Nijs Date: Tue, 2 Mar 2021 14:53:09 +0100 Subject: [PATCH 115/179] 77318: Google Scholar for entities: feedback --- .../app/rest/converter/ItemConverter.java | 31 ++----- .../dspace/app/rest/ItemRestRepositoryIT.java | 80 +++++++------------ 2 files changed, 37 insertions(+), 74 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java index ea50f82f98..811676c517 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ItemConverter.java @@ -10,23 +10,19 @@ package org.dspace.app.rest.converter; import java.sql.SQLException; import java.util.LinkedList; import java.util.List; -import java.util.UUID; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; import org.dspace.app.rest.model.ItemRest; import org.dspace.app.rest.model.MetadataValueList; import org.dspace.app.rest.projection.Projection; -import org.dspace.content.Entity; -import org.dspace.content.EntityType; import org.dspace.content.Item; import org.dspace.content.MetadataField; import org.dspace.content.MetadataValue; -import org.dspace.content.service.EntityService; import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.dspace.discovery.IndexableObject; -import org.dspace.xoai.services.api.context.ContextService; -import org.dspace.xoai.services.api.context.ContextServiceException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -41,18 +37,9 @@ public class ItemConverter extends DSpaceObjectConverter implements IndexableObjectConverter { - @Autowired - private ConverterService converter; - @Autowired private ItemService itemService; - @Autowired - private EntityService entityService; - - @Autowired - private ContextService contextService; - private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(ItemConverter.class); @Override @@ -63,16 +50,10 @@ public class ItemConverter item.setWithdrawn(obj.isWithdrawn()); item.setLastModified(obj.getLastModified()); - try { - Entity entity = entityService.findByItemId(contextService.getContext(), UUID.fromString(item.getId())); - EntityType entityType = entityService.getType(contextService.getContext(), entity); - if (entityType != null) { - item.setEntityType(entityType.getLabel()); - } - } catch (SQLException e) { - log.error("Error getting item's entity type", e); - } catch (ContextServiceException e) { - log.error("Error getting context", e); + List entityTypes = + itemService.getMetadata(obj, "relationship", "type", null, Item.ANY, false); + if (CollectionUtils.isNotEmpty(entityTypes) && StringUtils.isNotBlank(entityTypes.get(0).getValue())) { + item.setEntityType(entityTypes.get(0).getValue()); } return item; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java index b4b84cee38..7e7246f1b3 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java @@ -2779,9 +2779,19 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { .build(); context.restoreAuthSystemState(); - String token = getAuthToken(eperson.getEmail(), password); + String ePersonToken = getAuthToken(eperson.getEmail(), password); + getClient(ePersonToken).perform(get("/api/core/items/" + item.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$.entityType", is("Person"))); - getClient(token).perform(get("/api/core/items/" + item.getID())) + String adminToken = getAuthToken(admin.getEmail(), password); + getClient(adminToken).perform(get("/api/core/items/" + item.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$.entityType", is("Person"))); + + getClient().perform(get("/api/core/items/" + item.getID())) .andExpect(status().isOk()) .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) .andExpect(jsonPath("$.entityType", is("Person"))); @@ -2803,60 +2813,22 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { .build(); context.restoreAuthSystemState(); - String token = getAuthToken(eperson.getEmail(), password); - - getClient(token).perform(get("/api/core/items/" + item.getID())) + String ePersonToken = getAuthToken(eperson.getEmail(), password); + getClient(ePersonToken).perform(get("/api/core/items/" + item.getID())) .andExpect(status().isOk()) .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) .andExpect(jsonPath("$.entityType", is("Publication"))); - } - @Test - public void testEntityTypeOrgUnit() throws Exception { - context.turnOffAuthorisationSystem(); - EntityType orgUnit = EntityTypeBuilder.createEntityTypeBuilder(context, "OrgUnit").build(); - Community community = CommunityBuilder.createCommunity(context) - .withName("Parent Community") - .build(); - Collection collection = CollectionBuilder.createCollection(context, community).withName("Collection").build(); - Item item = ItemBuilder.createItem(context, collection) - .withTitle("OrgUnit1") - .withAuthor("Testy, TEst") - .withIssueDate("2015-01-01") - .withRelationshipType("OrgUnit") - .build(); - context.restoreAuthSystemState(); - - String token = getAuthToken(eperson.getEmail(), password); - - getClient(token).perform(get("/api/core/items/" + item.getID())) + String adminToken = getAuthToken(admin.getEmail(), password); + getClient(ePersonToken).perform(get("/api/core/items/" + item.getID())) .andExpect(status().isOk()) .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) - .andExpect(jsonPath("$.entityType", is("OrgUnit"))); - } + .andExpect(jsonPath("$.entityType", is("Publication"))); - @Test - public void testEntityTypeProject() throws Exception { - context.turnOffAuthorisationSystem(); - EntityType project = EntityTypeBuilder.createEntityTypeBuilder(context, "Project").build(); - Community community = CommunityBuilder.createCommunity(context) - .withName("Parent Community") - .build(); - Collection collection = CollectionBuilder.createCollection(context, community).withName("Collection").build(); - Item item = ItemBuilder.createItem(context, collection) - .withTitle("Project1") - .withAuthor("Testy, TEst") - .withIssueDate("2015-01-01") - .withRelationshipType("Project") - .build(); - context.restoreAuthSystemState(); - - String token = getAuthToken(eperson.getEmail(), password); - - getClient(token).perform(get("/api/core/items/" + item.getID())) + getClient().perform(get("/api/core/items/" + item.getID())) .andExpect(status().isOk()) .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) - .andExpect(jsonPath("$.entityType", is("Project"))); + .andExpect(jsonPath("$.entityType", is("Publication"))); } @Test @@ -2873,9 +2845,19 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { .build(); context.restoreAuthSystemState(); - String token = getAuthToken(eperson.getEmail(), password); + String ePersonToken = getAuthToken(eperson.getEmail(), password); + getClient(ePersonToken).perform(get("/api/core/items/" + item.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$.entityType", is(emptyOrNullString()))); - getClient(token).perform(get("/api/core/items/" + item.getID())) + String adminToken = getAuthToken(admin.getEmail(), password); + getClient(adminToken).perform(get("/api/core/items/" + item.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) + .andExpect(jsonPath("$.entityType", is(emptyOrNullString()))); + + getClient().perform(get("/api/core/items/" + item.getID())) .andExpect(status().isOk()) .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) .andExpect(jsonPath("$.entityType", is(emptyOrNullString()))); From 3fe194ae0948f73e2df65d35ec0ad56efcbfd9ee Mon Sep 17 00:00:00 2001 From: Samuel Date: Thu, 25 Feb 2021 18:45:38 +0100 Subject: [PATCH 116/179] taskid 77244 ItemMetadata caching bugfixes --- .../RelationshipMetadataServiceIT.java | 107 ++++- .../RelationshipDeleteRestRepositoryIT.java | 395 +++++++++++++++++- .../rest/RelationshipRestRepositoryIT.java | 4 + 3 files changed, 483 insertions(+), 23 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java b/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java index 798a549f9e..41a7e3c85d 100644 --- a/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java +++ b/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java @@ -187,13 +187,38 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa public void testDeleteAuthorRelationshipCopyToLeftItem() throws Exception { initPublicationAuthor(); context.turnOffAuthorisationSystem(); + + //verify the dc.contributor.author virtual metadata + List authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); + assertThat(authorList.size(), equalTo(1)); + + //verify the dc.contributor.author actual metadata + List plainMetadataAuthorList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null && + metadataValue.getMetadataField().getQualifier().equals("author")) + .collect(Collectors.toList()); + assertThat(plainMetadataAuthorList.size(), equalTo(0)); + + //verify there's no relation.isAuthorOfPublication actual metadata + List plainRelationshipMetadataList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication")) + .collect(Collectors.toList()); + assertThat(plainRelationshipMetadataList.size(), equalTo(0)); + //delete the relationship, copying the virtual metadata to actual metadata on the leftItem //leftItem is the publication relationshipService.delete(context, relationship, true, false); context.restoreAuthSystemState(); //verify the dc.contributor.author actual metadata - List authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); + plainMetadataAuthorList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null && + metadataValue.getMetadataField().getQualifier().equals("author")) + .collect(Collectors.toList()); + assertThat(plainMetadataAuthorList.size(), equalTo(1)); + + //verify the dc.contributor.author actual metadata + authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); assertThat(authorList.size(), equalTo(1)); assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName")); assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc")); @@ -201,10 +226,15 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author")); assertNull(authorList.get(0).getAuthority()); - //verify there's no relation.isAuthorOfPublication actual metadata + //verify there's relation.isAuthorOfPublication actual metadata + plainRelationshipMetadataList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication")) + .collect(Collectors.toList()); + assertThat(plainRelationshipMetadataList.size(), equalTo(1)); + //verify there's relation.isAuthorOfPublication actual metadata List relationshipMetadataList = itemService .getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY); - assertThat(relationshipMetadataList.size(), equalTo(0)); + assertThat(relationshipMetadataList.size(), equalTo(1)); //request the virtual metadata of the publication only List list = relationshipMetadataService.getRelationshipMetadata(leftItem, true); @@ -399,13 +429,38 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa public void testDeleteAuthorRelationshipCopyToLeftItemFromDefaultInDb() throws Exception { initPublicationAuthorWithCopyParams(true, false); context.turnOffAuthorisationSystem(); + + //verify the dc.contributor.author virtual metadata + List authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); + assertThat(authorList.size(), equalTo(1)); + + //verify the dc.contributor.author actual metadata + List plainMetadataAuthorList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null && + metadataValue.getMetadataField().getQualifier().equals("author")) + .collect(Collectors.toList()); + assertThat(plainMetadataAuthorList.size(), equalTo(0)); + + //verify there's no relation.isAuthorOfPublication actual metadata + List plainRelationshipMetadataList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication")) + .collect(Collectors.toList()); + assertThat(plainRelationshipMetadataList.size(), equalTo(0)); + //delete the relationship, copying the virtual metadata to actual metadata on the leftItem //leftItem is the publication relationshipService.delete(context, relationship); context.restoreAuthSystemState(); //verify the dc.contributor.author actual metadata - List authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); + plainMetadataAuthorList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null && + metadataValue.getMetadataField().getQualifier().equals("author")) + .collect(Collectors.toList()); + assertThat(plainMetadataAuthorList.size(), equalTo(1)); + + //verify the dc.contributor.author actual metadata + authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); assertThat(authorList.size(), equalTo(1)); assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName")); assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc")); @@ -413,10 +468,15 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author")); assertNull(authorList.get(0).getAuthority()); - //verify there's no relation.isAuthorOfPublication actual metadata + //verify there's relation.isAuthorOfPublication actual metadata + plainRelationshipMetadataList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication")) + .collect(Collectors.toList()); + assertThat(plainRelationshipMetadataList.size(), equalTo(1)); + //verify there's relation.isAuthorOfPublication actual metadata List relationshipMetadataList = itemService .getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY); - assertThat(relationshipMetadataList.size(), equalTo(0)); + assertThat(relationshipMetadataList.size(), equalTo(1)); //request the virtual metadata of the publication only List list = relationshipMetadataService.getRelationshipMetadata(leftItem, true); @@ -446,12 +506,36 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa public void testDeleteAuthorRelationshipCopyToBothItemsFromDefaultsInDb() throws Exception { initPublicationAuthorWithCopyParams(true, true); context.turnOffAuthorisationSystem(); + //verify the dc.contributor.author virtual metadata + List authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); + assertThat(authorList.size(), equalTo(1)); + + //verify the dc.contributor.author actual metadata + List plainMetadataAuthorList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null && + metadataValue.getMetadataField().getQualifier().equals("author")) + .collect(Collectors.toList()); + assertThat(plainMetadataAuthorList.size(), equalTo(0)); + + //verify there's no relation.isAuthorOfPublication actual metadata + List plainRelationshipMetadataList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication")) + .collect(Collectors.toList()); + assertThat(plainRelationshipMetadataList.size(), equalTo(0)); + //delete the relationship, copying the virtual metadata to actual metadata on the both items relationshipService.delete(context, relationship); context.restoreAuthSystemState(); //verify the dc.contributor.author actual metadata - List authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); + plainMetadataAuthorList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null && + metadataValue.getMetadataField().getQualifier().equals("author")) + .collect(Collectors.toList()); + assertThat(plainMetadataAuthorList.size(), equalTo(1)); + + //verify the dc.contributor.author actual metadata + authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); assertThat(authorList.size(), equalTo(1)); assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName")); assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc")); @@ -459,10 +543,15 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author")); assertNull(authorList.get(0).getAuthority()); - //verify there's no relation.isAuthorOfPublication actual metadata + //verify there's relation.isAuthorOfPublication actual metadata + plainRelationshipMetadataList = leftItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication")) + .collect(Collectors.toList()); + assertThat(plainRelationshipMetadataList.size(), equalTo(1)); + //verify there's relation.isAuthorOfPublication actual metadata List relationshipMetadataList = itemService .getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY); - assertThat(relationshipMetadataList.size(), equalTo(0)); + assertThat(relationshipMetadataList.size(), equalTo(1)); } @Test diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipDeleteRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipDeleteRestRepositoryIT.java index 9cc9ce51c9..8d97dcc502 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipDeleteRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipDeleteRestRepositoryIT.java @@ -7,8 +7,12 @@ */ package org.dspace.app.rest; +import static java.util.Arrays.asList; +import static java.util.stream.Collectors.toList; +import static org.dspace.content.Item.ANY; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.startsWith; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; @@ -221,6 +225,35 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio public void testDeleteAuthorRelationshipCopyToLeftItem() throws Exception { initPublicationAuthor(); + // Verify the dc.contributor.author virtual metadata of the left item + assertEquals( + 1, + itemService + .getMetadata(leftItem, "dc", "contributor", "author", Item.ANY) + .size() + ); + + // Verify there's no dc.contributor.author actual metadata on the left item + assertEquals( + 0, + leftItem.getMetadata() + .stream() + .filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier())) + .collect(toList()) + .size() + ); + + // Verify there's no relation.isAuthorOfPublication actual metadata on the left item + assertEquals( + 0, + leftItem.getMetadata() + .stream() + .filter(metadataValue -> "isAuthorOfPublication" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()) + .size() + ); + getClient(adminAuthToken).perform( delete("/api/core/relationships/" + relationship.getID() + "?copyVirtualMetadata=left")) .andExpect(status().isNoContent()); @@ -235,12 +268,35 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author")); assertNull(authorList.get(0).getAuthority()); - - // Check that the relation metadata values are gone because the relationship is gone List relationshipMetadataList = itemService .getMetadata(leftItem, "relation", "isAuthorOfPublication", null, Item.ANY); - assertThat(relationshipMetadataList.size(), equalTo(0)); + assertThat(relationshipMetadataList.size(), equalTo(1)); + // Verify there's dc.contributor.author actual metadata on the left item + assertEquals( + 1, + leftItem.getMetadata() + .stream() + .filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null && + metadataValue.getMetadataField().getQualifier().equals("author")) + .collect(toList()) + .size() + ); + + // Verify there's relation.isAuthorOfPublication actual metadata on the left item + assertEquals( + 1, + leftItem.getMetadata() + .stream() + .filter(metadataValue -> "isAuthorOfPublication" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()) + .size() + ); + + // Check right item to ensure that no metadata is copied + + rightItem = context.reloadEntity(rightItem); relationshipMetadataList = itemService .getMetadata(rightItem, "relation", "isPublicationOfAuthor", null, Item.ANY); assertThat(relationshipMetadataList.size(), equalTo(0)); @@ -250,6 +306,27 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio public void testAuthorDeleteRelationshipCopyToRightItem() throws Exception { initPublicationAuthor(); + // Verify there's no dc.contributor.author actual metadata on the right item + assertEquals( + 0, + rightItem.getMetadata() + .stream() + .filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier())) + .collect(toList()) + .size() + ); + + // Verify there's no relation.isPublicationOfAuthor actual metadata on the right item + assertEquals( + 0, + rightItem.getMetadata() + .stream() + .filter(metadataValue -> "isPublicationOfAuthor" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()) + .size() + ); + getClient(adminAuthToken).perform( delete("/api/core/relationships/" + relationship.getID() + "?copyVirtualMetadata=right")) .andExpect(status().isNoContent()); @@ -259,14 +336,27 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio List authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY); assertThat(authorList.size(), equalTo(0)); - // Check that the relation metadata values are gone because the relationship is gone List relationshipMetadataList = itemService .getMetadata(leftItem, "relation", "isAuthorOfPublication", null, Item.ANY); assertThat(relationshipMetadataList.size(), equalTo(0)); + // Check right item to ensure that the metadata is copied + + rightItem = itemService.find(context, rightItem.getID()); relationshipMetadataList = itemService .getMetadata(rightItem, "relation", "isPublicationOfAuthor", null, Item.ANY); - assertThat(relationshipMetadataList.size(), equalTo(0)); + assertThat(relationshipMetadataList.size(), equalTo(1)); + + // Verify there's relation.isPublicationOfAuthor actual metadata on the right item + assertEquals( + 1, + rightItem.getMetadata() + .stream() + .filter(metadataValue -> "isPublicationOfAuthor" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()) + .size() + ); // There is no additional Metadata to check on the rightItem because the configuration of the virtual // metadata holds no config to display virtual metadata on the author of the publication @@ -291,11 +381,44 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio List relationshipMetadataList = itemService .getMetadata(leftItem, "relation", "isAuthorOfPublication", null, Item.ANY); - assertThat(relationshipMetadataList.size(), equalTo(0)); + assertThat(relationshipMetadataList.size(), equalTo(1)); + // Verify there's dc.contributor.author actual metadata on the left item + assertEquals( + 1, + leftItem.getMetadata() + .stream() + .filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier())) + .collect(toList()) + .size() + ); + + // Verify there's relation.isAuthorOfPublication actual metadata on the left item + assertEquals( + 1, + leftItem.getMetadata() + .stream() + .filter(metadataValue -> "isAuthorOfPublication" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()) + .size() + ); + + rightItem = itemService.find(context, rightItem.getID()); relationshipMetadataList = itemService .getMetadata(rightItem, "relation", "isPublicationOfAuthor", null, Item.ANY); - assertThat(relationshipMetadataList.size(), equalTo(0)); + assertThat(relationshipMetadataList.size(), equalTo(1)); + + // Verify there's relation.isPublicationOfAuthor actual metadata on the right item + assertEquals( + 1, + rightItem.getMetadata() + .stream() + .filter(metadataValue -> "isPublicationOfAuthor" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()) + .size() + ); // There is no additional Metadata to check on the rightItem because the configuration of the virtual // metadata holds no config to display virtual metadata on the author of the publication @@ -375,6 +498,32 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio public void deleteItemCopyVirtualMetadataAll() throws Exception { initPersonProjectPublication(); + for (Item item : asList(publicationItem, projectItem)) { + + // Verify the dc.contributor.author virtual metadata + assertEquals( + 1, + itemService.getMetadata(item, "dc", "contributor", "author", ANY).size() + ); + + // Verify there's no dc.contributor.author actual metadata on the item + assertEquals( + 0, + item.getMetadata().stream() + .filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier())) + .collect(toList()).size() + ); + + // Verify there's no relation.isAuthorOfPublication actual metadata on the item + assertEquals( + 0, + item.getMetadata().stream() + .filter(metadataValue -> "isAuthorOfPublication" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()).size() + ); + } + getClient(adminAuthToken).perform( delete("/api/core/items/" + personItem.getID() + "?copyVirtualMetadata=all")) .andExpect(status().isNoContent()); @@ -387,7 +536,26 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio assertNull(publicationAuthorList.get(0).getAuthority()); List publicationRelationships = itemService.getMetadata(publicationItem, "relation", "isAuthorOfPublication", Item.ANY, Item.ANY); - assertThat(publicationRelationships.size(), equalTo(0)); + assertThat(publicationRelationships.size(), equalTo(1)); + + // Verify there's dc.contributor.author actual metadata on the publication item + assertEquals( + 1, + publicationItem.getMetadata().stream() + .filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier())) + .collect(toList()) + .size() + ); + + // Verify there's relation.isAuthorOfPublication actual metadata on the publication item + assertEquals( + 1, + publicationItem.getMetadata().stream() + .filter(metadataValue -> "isAuthorOfPublication" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()) + .size() + ); projectItem = itemService.find(context, projectItem.getID()); List projectAuthorList = itemService.getMetadata(projectItem, @@ -397,13 +565,58 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio assertNull(projectAuthorList.get(0).getAuthority()); List projectRelationships = itemService.getMetadata(projectItem, "relation", "isPersonOfProject", Item.ANY, Item.ANY); - assertThat(projectRelationships.size(), equalTo(0)); + assertThat(projectRelationships.size(), equalTo(1)); + + // Verify there's dc.contributor.author actual metadata on the project item + assertEquals( + 1, + projectItem.getMetadata().stream() + .filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier())) + .collect(toList()) + .size() + ); + + // Verify there's relation.isPersonOfProject actual metadata on the project item + assertEquals( + 1, + projectItem.getMetadata().stream() + .filter(metadataValue -> "isPersonOfProject" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()) + .size() + ); } @Test public void deleteItemCopyVirtualMetadataOneType() throws Exception { initPersonProjectPublication(); + for (Item item : asList(publicationItem, projectItem)) { + + // Verify the dc.contributor.author virtual metadata + assertEquals( + 1, + itemService.getMetadata(item, "dc", "contributor", "author", ANY).size() + ); + + // Verify there's no dc.contributor.author actual metadata on the item + assertEquals( + 0, + item.getMetadata().stream() + .filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier())) + .collect(toList()).size() + ); + + // Verify there's no relation.isAuthorOfPublication actual metadata on the item + assertEquals( + 0, + item.getMetadata().stream() + .filter(metadataValue -> "isAuthorOfPublication" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()).size() + ); + } + getClient(adminAuthToken).perform( delete("/api/core/items/" + personItem.getID() + "?copyVirtualMetadata=" + publicationPersonRelationshipType.getID())) @@ -417,7 +630,26 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio assertNull(publicationAuthorList.get(0).getAuthority()); List publicationRelationships = itemService.getMetadata(publicationItem, "relation", "isAuthorOfPublication", Item.ANY, Item.ANY); - assertThat(publicationRelationships.size(), equalTo(0)); + assertThat(publicationRelationships.size(), equalTo(1)); + + // Verify there's dc.contributor.author actual metadata on the publication item + assertEquals( + 1, + publicationItem.getMetadata().stream() + .filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier())) + .collect(toList()) + .size() + ); + + // Verify there's relation.isAuthorOfPublication actual metadata on the publication item + assertEquals( + 1, + publicationItem.getMetadata().stream() + .filter(metadataValue -> "isAuthorOfPublication" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()) + .size() + ); projectItem = itemService.find(context, projectItem.getID()); List projectAuthorList = itemService.getMetadata(projectItem, @@ -432,6 +664,32 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio public void deleteItemCopyVirtualMetadataTwoTypes() throws Exception { initPersonProjectPublication(); + for (Item item : asList(publicationItem, projectItem)) { + + // Verify the dc.contributor.author virtual metadata + assertEquals( + 1, + itemService.getMetadata(item, "dc", "contributor", "author", ANY).size() + ); + + // Verify there's no dc.contributor.author actual metadata on the item + assertEquals( + 0, + item.getMetadata().stream() + .filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier())) + .collect(toList()).size() + ); + + // Verify there's no relation.isAuthorOfPublication actual metadata on the item + assertEquals( + 0, + item.getMetadata().stream() + .filter(metadataValue -> "isAuthorOfPublication" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()).size() + ); + } + getClient(adminAuthToken).perform( delete("/api/core/items/" + personItem.getID() + "?copyVirtualMetadata=" + publicationPersonRelationshipType.getID() @@ -446,7 +704,26 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio assertNull(publicationAuthorList.get(0).getAuthority()); List publicationRelationships = itemService.getMetadata(publicationItem, "relation", "isAuthorOfPublication", Item.ANY, Item.ANY); - assertThat(publicationRelationships.size(), equalTo(0)); + assertThat(publicationRelationships.size(), equalTo(1)); + + // Verify there's dc.contributor.author actual metadata on the publication item + assertEquals( + 1, + publicationItem.getMetadata().stream() + .filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier())) + .collect(toList()) + .size() + ); + + // Verify there's relation.isAuthorOfPublication actual metadata on the publication item + assertEquals( + 1, + publicationItem.getMetadata().stream() + .filter(metadataValue -> "isAuthorOfPublication" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()) + .size() + ); projectItem = itemService.find(context, projectItem.getID()); List projectAuthorList = itemService.getMetadata(projectItem, @@ -456,7 +733,26 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio assertNull(projectAuthorList.get(0).getAuthority()); List projectRelationships = itemService.getMetadata(projectItem, "relation", "isPersonOfProject", Item.ANY, Item.ANY); - assertThat(projectRelationships.size(), equalTo(0)); + assertThat(projectRelationships.size(), equalTo(1)); + + // Verify there's dc.contributor.author actual metadata on the project item + assertEquals( + 1, + projectItem.getMetadata().stream() + .filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier())) + .collect(toList()) + .size() + ); + + // Verify there's relation.isPersonOfProject actual metadata on the project item + assertEquals( + 1, + projectItem.getMetadata().stream() + .filter(metadataValue -> "isPersonOfProject" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()) + .size() + ); } @Test @@ -520,6 +816,32 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio public void deleteItemCopyVirtualMetadataAllNoPermissions() throws Exception { initPersonProjectPublication(); + for (Item item : asList(publicationItem, projectItem)) { + + // Verify the dc.contributor.author virtual metadata + assertEquals( + 1, + itemService.getMetadata(item, "dc", "contributor", "author", ANY).size() + ); + + // Verify there's no dc.contributor.author actual metadata on the item + assertEquals( + 0, + item.getMetadata().stream() + .filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier())) + .collect(toList()).size() + ); + + // Verify there's no relation.isAuthorOfPublication actual metadata on the item + assertEquals( + 0, + item.getMetadata().stream() + .filter(metadataValue -> "isAuthorOfPublication" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()).size() + ); + } + getClient(getAuthToken(eperson.getEmail(), password)).perform( delete("/api/core/items/" + personItem.getID())) .andExpect(status().isForbidden()); @@ -608,6 +930,32 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio public void deleteItemCopyVirtualMetadataConfigured() throws Exception { initPersonProjectPublication(); + for (Item item : asList(publicationItem, projectItem)) { + + // Verify the dc.contributor.author virtual metadata + assertEquals( + 1, + itemService.getMetadata(item, "dc", "contributor", "author", ANY).size() + ); + + // Verify there's no dc.contributor.author actual metadata on the item + assertEquals( + 0, + item.getMetadata().stream() + .filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier())) + .collect(toList()).size() + ); + + // Verify there's no relation.isAuthorOfPublication actual metadata on the item + assertEquals( + 0, + item.getMetadata().stream() + .filter(metadataValue -> "isAuthorOfPublication" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()).size() + ); + } + getClient(adminAuthToken).perform( delete("/api/core/items/" + personItem.getID() + "?copyVirtualMetadata=configured")) .andExpect(status().isNoContent()); @@ -629,7 +977,26 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio assertNull(projectAuthorList.get(0).getAuthority()); List projectRelationships = itemService.getMetadata(projectItem, "relation", "isPersonOfProject", Item.ANY, Item.ANY); - assertThat(projectRelationships.size(), equalTo(0)); + assertThat(projectRelationships.size(), equalTo(1)); + + // Verify there's dc.contributor.author actual metadata on the project item + assertEquals( + 1, + projectItem.getMetadata().stream() + .filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier())) + .collect(toList()) + .size() + ); + + // Verify there's relation.isPersonOfProject actual metadata on the project item + assertEquals( + 1, + projectItem.getMetadata().stream() + .filter(metadataValue -> "isPersonOfProject" + .equals(metadataValue.getMetadataField().getElement())) + .collect(toList()) + .size() + ); } @Test @@ -653,7 +1020,7 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio assertNull(publicationAuthorList.get(0).getAuthority()); List publicationRelationships = itemService.getMetadata(publicationItem, "relation", "isAuthorOfPublication", Item.ANY, Item.ANY); - assertThat(publicationRelationships.size(), equalTo(0)); + assertThat(publicationRelationships.size(), equalTo(1)); projectItem = itemService.find(context, projectItem.getID()); List projectAuthorList = itemService.getMetadata(projectItem, diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipRestRepositoryIT.java index d8f4188a66..313bd0afc8 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipRestRepositoryIT.java @@ -775,6 +775,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest .andExpect(status().isCreated()) .andDo(result -> idRef2.set(read(result.getResponse().getContentAsString(), "$.id"))); + publication1 = itemService.find(context, publication1.getID()); list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY); // Ensure that we now have three dc.contributor.author mdv ("Smith, Donald", "plain text", "Smith, Maria" // In that order which will be checked below the rest call @@ -801,6 +802,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest itemService.update(context, publication1); context.restoreAuthSystemState(); + publication1 = itemService.find(context, publication1.getID()); list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY); // Assert that the list of dc.contributor.author mdv is now of size 4 in the following order: @@ -838,6 +840,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest .andExpect(status().isCreated()) .andDo(result -> idRef3.set(read(result.getResponse().getContentAsString(), "$.id"))); + publication1 = itemService.find(context, publication1.getID()); list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY); // Assert that our dc.contributor.author mdv list is now of size 5 assertEquals(5, list.size()); @@ -901,6 +904,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest itemService.update(context, publication1); context.restoreAuthSystemState(); + publication1 = itemService.find(context, publication1.getID()); list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY); assertEquals(10, list.size()); From 5f6ae856cd69c1c4dff1d35a866c0b3adf563473 Mon Sep 17 00:00:00 2001 From: Raf Ponsaerts Date: Thu, 4 Mar 2021 15:28:38 +0100 Subject: [PATCH 117/179] Fixed browse tests --- .../java/org/dspace/builder/ItemBuilder.java | 3 ++- .../app/rest/BrowsesResourceControllerIT.java | 24 +++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java b/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java index c53fb2d9f3..dd033223a4 100644 --- a/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java @@ -87,7 +87,8 @@ public class ItemBuilder extends AbstractDSpaceObjectBuilder { } public ItemBuilder withSubject(final String subject, final String authority, final int confidence) { - return addMetadataValue(item, MetadataSchemaEnum.DC.getName(), "subject", null, null, subject, authority, confidence); + return addMetadataValue(item, MetadataSchemaEnum.DC.getName(), "subject", null, null, + subject, authority, confidence); } public ItemBuilder withRelationshipType(final String relationshipType) { diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java index 7bec3f3041..0defa71513 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java @@ -250,24 +250,24 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe .withTitle("Public item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") - .withSubject("ExtraEntry", "authority_1", 600) + .withSubject("History of religion", "VR110102", 600) .build(); Item publicItem2 = ItemBuilder.createItem(context, col2) .withTitle("Public item 2") .withIssueDate("2016-02-13") .withAuthor("Smith, Maria").withAuthor("Doe, Jane") - .withSubject("TestingForMore", "authority_2", 600) - .withSubject("ExtraEntry", "authority_1", 600) + .withSubject("Church studies", "VR110103", 600) + .withSubject("History of religion", "VR110102", 600) .build(); Item publicItem3 = ItemBuilder.createItem(context, col2) .withTitle("Public item 2") .withIssueDate("2016-02-13") .withAuthor("Smith, Maria").withAuthor("Doe, Jane") - .withSubject("AnotherTest", "authority_3", 600) - .withSubject("TestingForMore", "authority_2", 600) - .withSubject("ExtraEntry", "authority_1", 600) + .withSubject("Missionary studies", "VR110104", 600) + .withSubject("Church studies", "VR110103", 600) + .withSubject("History of religion", "VR110102", 600) .build(); context.restoreAuthSystemState(); @@ -290,9 +290,9 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe //Check that the subject matches as expected //Verify that they're sorted alphabetically .andExpect(jsonPath("$._embedded.entries", - contains(BrowseEntryResourceMatcher.matchBrowseEntry("AnotherTest", "authority_3", 1), - BrowseEntryResourceMatcher.matchBrowseEntry("ExtraEntry", "authority_1", 3), - BrowseEntryResourceMatcher.matchBrowseEntry("TestingForMore", "authority_2", 2) + containsInAnyOrder(BrowseEntryResourceMatcher.matchBrowseEntry("Missionary studies", "VR110104", 1), + BrowseEntryResourceMatcher.matchBrowseEntry("History of religion", "VR110102", 3), + BrowseEntryResourceMatcher.matchBrowseEntry("Church studies", "VR110103", 2) ))); getClient().perform(get("/api/discover/browses/subject/entries") @@ -311,9 +311,9 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe //Check that the subject matches as expected //Verify that they're sorted alphabetically .andExpect(jsonPath("$._embedded.entries", - contains(BrowseEntryResourceMatcher.matchBrowseEntry("AnotherTest", "authority_3", 1), - BrowseEntryResourceMatcher.matchBrowseEntry("ExtraEntry", "authority_1", 3), - BrowseEntryResourceMatcher.matchBrowseEntry("TestingForMore", "authority_2", 2) + containsInAnyOrder(BrowseEntryResourceMatcher.matchBrowseEntry("Missionary studies", "VR110104", 1), + BrowseEntryResourceMatcher.matchBrowseEntry("History of religion", "VR110102", 3), + BrowseEntryResourceMatcher.matchBrowseEntry("Church studies", "VR110103", 2) ))); } From 990ae7750bfe3259d35537844c65aef11e24933f Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Fri, 5 Mar 2021 08:59:49 +0100 Subject: [PATCH 118/179] 77228: Implement authority vocabulary fix for facet IT --- .../app/rest/DiscoveryRestControllerIT.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java index 40e91dff34..403d469d7b 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java @@ -215,7 +215,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .withIssueDate("2017-10-17") .withAuthor("Smith, Donald") .withAuthor("Doe, John") - .withSubject("ExtraEntry", "authority_1", 600) + .withSubject("History of religion", "VR110102", 600) .build(); Item publicItem2 = ItemBuilder.createItem(context, col2) @@ -223,8 +223,8 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .withIssueDate("2016-02-13") .withAuthor("Smith, Maria") .withAuthor("Doe, Jane") - .withSubject("TestingForMore", "authority_2", 600) - .withSubject("ExtraEntry", "authority_1", 600) + .withSubject("Church studies", "VR110103", 600) + .withSubject("History of religion", "VR110102", 600) .build(); Item publicItem3 = ItemBuilder.createItem(context, col2) @@ -235,9 +235,9 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .withAuthor("test, test") .withAuthor("test2, test2") .withAuthor("Maybe, Maybe") - .withSubject("AnotherTest", "authority_3", 600) - .withSubject("TestingForMore", "authority_2", 600) - .withSubject("ExtraEntry", "authority_1", 600) + .withSubject("Missionary studies", "VR110104", 600) + .withSubject("Church studies", "VR110103", 600) + .withSubject("History of religion", "VR110102", 600) .build(); context.restoreAuthSystemState(); @@ -268,8 +268,8 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest // up in different items //These subjects are the most used ones. Only two show up because of the size. .andExpect(jsonPath("$._embedded.values", containsInAnyOrder( - FacetValueMatcher.entrySubject("ExtraEntry", 3), - FacetValueMatcher.entrySubject("TestingForMore", 2) + FacetValueMatcher.entrySubject("History of religion", 3), + FacetValueMatcher.entrySubject("Church studies", 2) ))) ; } From fea0a3a89694cf045be71ba995e1241497d1330d Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Fri, 5 Mar 2021 10:19:38 +0100 Subject: [PATCH 119/179] 77228: Fix line length --- .../app/rest/BrowsesResourceControllerIT.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java index 0defa71513..688a55aedd 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java @@ -289,11 +289,15 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe //Check the embedded resources and that they're sorted alphabetically //Check that the subject matches as expected //Verify that they're sorted alphabetically - .andExpect(jsonPath("$._embedded.entries", - containsInAnyOrder(BrowseEntryResourceMatcher.matchBrowseEntry("Missionary studies", "VR110104", 1), - BrowseEntryResourceMatcher.matchBrowseEntry("History of religion", "VR110102", 3), - BrowseEntryResourceMatcher.matchBrowseEntry("Church studies", "VR110103", 2) - ))); + .andExpect( + jsonPath("$._embedded.entries", + containsInAnyOrder( + BrowseEntryResourceMatcher.matchBrowseEntry("Missionary studies", "VR110104", 1), + BrowseEntryResourceMatcher.matchBrowseEntry("History of religion", "VR110102", 3), + BrowseEntryResourceMatcher.matchBrowseEntry("Church studies", "VR110103", 2) + ) + ) + ); getClient().perform(get("/api/discover/browses/subject/entries") .param("sort", "value,desc")) @@ -310,11 +314,15 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe //Check the embedded resources and that they're sorted alphabetically //Check that the subject matches as expected //Verify that they're sorted alphabetically - .andExpect(jsonPath("$._embedded.entries", - containsInAnyOrder(BrowseEntryResourceMatcher.matchBrowseEntry("Missionary studies", "VR110104", 1), - BrowseEntryResourceMatcher.matchBrowseEntry("History of religion", "VR110102", 3), - BrowseEntryResourceMatcher.matchBrowseEntry("Church studies", "VR110103", 2) - ))); + .andExpect( + jsonPath("$._embedded.entries", + containsInAnyOrder( + BrowseEntryResourceMatcher.matchBrowseEntry("Missionary studies", "VR110104", 1), + BrowseEntryResourceMatcher.matchBrowseEntry("History of religion", "VR110102", 3), + BrowseEntryResourceMatcher.matchBrowseEntry("Church studies", "VR110103", 2) + ) + ) + ); } @Test From 0df65bfa9b5f50d67270782cf6fee95630385a05 Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Fri, 5 Mar 2021 11:26:44 +0100 Subject: [PATCH 120/179] 77228: Fix authority browse/facet IT side effects --- .../app/rest/BrowsesResourceControllerIT.java | 17 +++++++++++++---- .../app/rest/DiscoveryRestControllerIT.java | 14 ++++++++++++-- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java index 688a55aedd..2c818c1ec9 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java @@ -225,6 +225,9 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe @Test public void findBrowseBySubjectEntriesWithAuthority() throws Exception { + String ogDcSubjectChoices = configurationService.getProperty("choices.plugin.dc.subject"); + String ogDcSubjectAuthorityControlled = configurationService.getProperty("authority.controlled.dc.subject"); + configurationService.setProperty("choices.plugin.dc.subject", "SolrSubjectAuthority"); configurationService.setProperty("authority.controlled.dc.subject", @@ -318,11 +321,19 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe jsonPath("$._embedded.entries", containsInAnyOrder( BrowseEntryResourceMatcher.matchBrowseEntry("Missionary studies", "VR110104", 1), - BrowseEntryResourceMatcher.matchBrowseEntry("History of religion", "VR110102", 3), - BrowseEntryResourceMatcher.matchBrowseEntry("Church studies", "VR110103", 2) + BrowseEntryResourceMatcher.matchBrowseEntry("History of religion", "VR110102", 3), + BrowseEntryResourceMatcher.matchBrowseEntry("Church studies", "VR110103", 2) ) ) ); + + // Clean up configuration for the following tests + configurationService.setProperty("choices.plugin.dc.subject", + ogDcSubjectChoices); + configurationService.setProperty("authority.controlled.dc.subject", + ogDcSubjectAuthorityControlled); + + metadataAuthorityService.clearCache(); } @Test @@ -1231,6 +1242,4 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe .andExpect(jsonPath("$._embedded.items[0]._embedded.owningCollection._embedded.adminGroup", nullValue())); } - - } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java index 403d469d7b..5f11ff91f5 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java @@ -188,6 +188,9 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest @Test public void discoverFacetsAuthorWithAuthorityWithSizeParameter() throws Exception { + String ogDcSubjectChoices = configurationService.getProperty("choices.plugin.dc.subject"); + String ogDcSubjectAuthorityControlled = configurationService.getProperty("authority.controlled.dc.subject"); + configurationService.setProperty("choices.plugin.dc.subject", "SolrSubjectAuthority"); configurationService.setProperty("authority.controlled.dc.subject", @@ -270,8 +273,15 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest .andExpect(jsonPath("$._embedded.values", containsInAnyOrder( FacetValueMatcher.entrySubject("History of religion", 3), FacetValueMatcher.entrySubject("Church studies", 2) - ))) - ; + ))); + + // Clean up configuration for the following tests + configurationService.setProperty("choices.plugin.dc.subject", + ogDcSubjectChoices); + configurationService.setProperty("authority.controlled.dc.subject", + ogDcSubjectAuthorityControlled); + + metadataAuthorityService.clearCache(); } @Test From 7fc96dc14847f423a7dfa9f8e231d15578d5128c Mon Sep 17 00:00:00 2001 From: j4bbi Date: Fri, 5 Mar 2021 13:39:34 +0000 Subject: [PATCH 121/179] Exposed more parameters for DBCP2 --- dspace/config/dspace.cfg | 29 ++++++++++++++++++--- dspace/config/spring/api/core-hibernate.xml | 5 ++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index 1470c99067..b097b54b70 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -72,19 +72,42 @@ db.password = dspace # so this may be set to ${db.username} in most scenarios. db.schema = public -## Connection pool parameters +## Database Connection pool parameters +# DSpace wraps around the Apache Commons DBCP2 component, to read about its configuration +# see: https://commons.apache.org/proper/commons-dbcp/configuration.html -# Maximum number of DB connections in pool (default = 30) +# Maximum number of active DB connections in pool (-1 = unlimited) +# (default = 30) db.maxconnections = 30 -# Maximum time to wait before giving up if all connections in pool are busy (milliseconds) +# Maximum time to wait before giving up if all connections in pool are busy (milliseconds), (-1 = unlimited) # (default = 5000ms or 5 seconds) db.maxwait = 5000 +# Minimum number of idle connections in pool +# (default = 0) +db.minidle = 0 + # Maximum number of idle connections in pool (-1 = unlimited) # (default = 10) db.maxidle = 10 +# The initial number of connections created when the pool is started +# (default = 0) +db.initialsize = 0 + +# The maximum lifetime in milliseconds of a connection. (-1 = unlimited) +# (default = -1) +db.maxconnlifetime = -1 + +# Remove abandoned connections. +# (default = false) +db.removeabandoned = false + +# Remove abandoned timeout. Timeout in seconds before an abandoned connection can be removed. +# (default = 300 or 5 minutes) +db.removeabandonedtimeout = 300 + # Whether or not to allow for an entire 'clean' of the DSpace database. # By default, this setting is 'true', which ensures that the 'dspace database clean' command # does nothing (except return an error message saying clean is disabled) diff --git a/dspace/config/spring/api/core-hibernate.xml b/dspace/config/spring/api/core-hibernate.xml index 7655922f80..76d7b5b1ad 100644 --- a/dspace/config/spring/api/core-hibernate.xml +++ b/dspace/config/spring/api/core-hibernate.xml @@ -43,9 +43,14 @@ + + + + +
\ No newline at end of file From 379dd2d8a7edba9e0b973365b250a2dc52033fc0 Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Fri, 5 Mar 2021 16:55:41 +0100 Subject: [PATCH 122/179] 77228: Fix line length --- .../dspace/app/rest/matcher/BrowseEntryResourceMatcher.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/BrowseEntryResourceMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/BrowseEntryResourceMatcher.java index 614b03601c..d2fcfbb4c7 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/BrowseEntryResourceMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/BrowseEntryResourceMatcher.java @@ -35,11 +35,11 @@ public class BrowseEntryResourceMatcher { ); } - public static Matcher matchBrowseEntry(String entryValue, String authorityValue, int expectedCount) { + public static Matcher matchBrowseEntry(String value, String authority, int expectedCount) { return allOf( //Check core metadata (the JSON Path expression evaluates to a collection so we have to use contains) - hasJsonPath("$.value", is(entryValue)), - hasJsonPath("$.authority", is(authorityValue)), + hasJsonPath("$.value", is(value)), + hasJsonPath("$.authority", is(authority)), hasJsonPath("$.count", is(expectedCount)), //Check links matchItemLinks() From a8d99bba15b4df491fda2390fe3611ef2e6336fd Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 5 Mar 2021 14:57:39 -0600 Subject: [PATCH 123/179] Address feedback. Restore a few settings which are still used --- dspace-api/src/main/resources/Messages.properties | 1 + dspace/config/dspace.cfg | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/dspace-api/src/main/resources/Messages.properties b/dspace-api/src/main/resources/Messages.properties index bf329a5d73..97a7158205 100644 --- a/dspace-api/src/main/resources/Messages.properties +++ b/dspace-api/src/main/resources/Messages.properties @@ -88,6 +88,7 @@ org.dspace.checker.SimpleReporterImpl.size org.dspace.checker.SimpleReporterImpl.source = Source org.dspace.checker.SimpleReporterImpl.store-number = Store Number org.dspace.checker.SimpleReporterImpl.unchecked-bitstream-report = The following is a UN-CHECKED BITSTREAM REPORT report for +org.dspace.eperson.X509Authentication.title = Enter DSpace using Web Certificate org.dspace.eperson.Subscribe.authors = Authors: org.dspace.eperson.Subscribe.id = ID: org.dspace.eperson.Subscribe.new-items = New Items: diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index 273d85b47b..5891b31c90 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -890,6 +890,10 @@ thumbnail.maxheight = 80 # more in check. (Only used by JPEGFilter) thumbnail.blurring = true +# High quality scaling option. Setting to true can dramatically increase +# image quality, but it takes longer to create thumbnails. (Only used by JPEGFilter) +thumbnail.hqscaling = true + #### Settings for BrandedPreviewJPEGFilter #### # max dimensions of the preview image webui.preview.maxwidth = 600 From 2f33245f57d18884e0aaa83f8312ea36d3ac87e7 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 5 Mar 2021 15:02:35 -0600 Subject: [PATCH 124/179] Remove unused log.init.config --- dspace/config/dspace.cfg | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index 5891b31c90..e9ca99957e 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -171,13 +171,7 @@ mail.message.headers = charset # Moved to config/spring/api/bitstore.xml ##### Logging configuration ##### -# Override default log4j configuration file -# You may provide your own configuration here, existing alternatives are: -# log.init.config = ${dspace.dir}/config/log4j2-console.xml -# TODO: WHERE IS THIS USED? -log.init.config = ${dspace.dir}/config/log4j2.xml - -# All other log4j settings moved to config/log4j2.xml +# All log4j settings moved to config/log4j2.xml ##### DOI registration agency credentials ###### # To mint DOIs you have to use a DOI registration agency like DataCite. Several From 0cd1e1b63612e21662bce2fe286e8e73c9395d2f Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 5 Mar 2021 15:28:25 -0600 Subject: [PATCH 125/179] Remove unused JSON request handlers --- dspace/solr/oai/conf/solrconfig.xml | 10 ---------- dspace/solr/search/conf/solrconfig.xml | 10 ---------- dspace/solr/statistics/conf/solrconfig.xml | 10 ---------- 3 files changed, 30 deletions(-) diff --git a/dspace/solr/oai/conf/solrconfig.xml b/dspace/solr/oai/conf/solrconfig.xml index bb7e18e508..02789fa3c2 100644 --- a/dspace/solr/oai/conf/solrconfig.xml +++ b/dspace/solr/oai/conf/solrconfig.xml @@ -110,16 +110,6 @@ - - - - explicit - json - true - item.handle - - - diff --git a/dspace/solr/search/conf/solrconfig.xml b/dspace/solr/search/conf/solrconfig.xml index 07b20553ec..204c1a056e 100644 --- a/dspace/solr/search/conf/solrconfig.xml +++ b/dspace/solr/search/conf/solrconfig.xml @@ -122,16 +122,6 @@ - - - - explicit - json - true - search_text - - - diff --git a/dspace/solr/statistics/conf/solrconfig.xml b/dspace/solr/statistics/conf/solrconfig.xml index b73f8ee613..9a6c161462 100644 --- a/dspace/solr/statistics/conf/solrconfig.xml +++ b/dspace/solr/statistics/conf/solrconfig.xml @@ -110,16 +110,6 @@ - - - - explicit - json - true - id - - - From ece20cf1d4fba8c13be888ac3a934a70df2a7da3 Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Tue, 9 Mar 2021 09:44:50 +0100 Subject: [PATCH 126/179] 77228: Fix browse/facet authority IT cleanup --- .../authority/MetadataAuthorityServiceImpl.java | 1 - .../AbstractIntegrationTestWithDatabase.java | 13 +++++++++++++ .../app/rest/BrowsesResourceControllerIT.java | 11 ----------- .../app/rest/DiscoveryRestControllerIT.java | 15 ++------------- .../rest/matcher/BrowseEntryResourceMatcher.java | 6 +----- .../app/rest/matcher/FacetValueMatcher.java | 8 ++++++++ 6 files changed, 24 insertions(+), 30 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/authority/MetadataAuthorityServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/authority/MetadataAuthorityServiceImpl.java index fa2abd0bc9..5593aabd63 100644 --- a/dspace-api/src/main/java/org/dspace/content/authority/MetadataAuthorityServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/authority/MetadataAuthorityServiceImpl.java @@ -226,7 +226,6 @@ public class MetadataAuthorityServiceImpl implements MetadataAuthorityService { @Override public void clearCache() { controlled.clear(); - isAuthorityRequired.clear(); minConfidence.clear(); isAuthorityRequired = null; diff --git a/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java b/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java index 2b6a73673a..cd49b5cca4 100644 --- a/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java +++ b/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java @@ -19,6 +19,7 @@ import org.dspace.authority.MockAuthoritySolrServiceImpl; import org.dspace.authorize.AuthorizeException; import org.dspace.builder.AbstractBuilder; import org.dspace.content.Community; +import org.dspace.content.authority.MetadataAuthorityServiceImpl; import org.dspace.core.Context; import org.dspace.core.I18nUtil; import org.dspace.discovery.MockSolrSearchCore; @@ -197,6 +198,8 @@ public class AbstractIntegrationTestWithDatabase extends AbstractDSpaceIntegrati // Reload our ConfigurationService (to reset configs to defaults again) DSpaceServicesFactory.getInstance().getConfigurationService().reloadConfig(); + cleanupCache(serviceManager); + AbstractBuilder.cleanupBuilderCache(); // NOTE: we explicitly do NOT destroy our default eperson & admin as they @@ -206,6 +209,16 @@ public class AbstractIntegrationTestWithDatabase extends AbstractDSpaceIntegrati } } + /** + * Clean up service caches after tests + * @param serviceManager + */ + private void cleanupCache(ServiceManager serviceManager) { + MetadataAuthorityServiceImpl metadataAuthorityService = serviceManager + .getServiceByName(null, MetadataAuthorityServiceImpl.class); + metadataAuthorityService.clearCache(); + } + /** * Utility method to cleanup a created Context object (to save memory). * This can also be used by individual tests to cleanup context objects they create. diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java index 2c818c1ec9..bb40609ff1 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java @@ -225,9 +225,6 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe @Test public void findBrowseBySubjectEntriesWithAuthority() throws Exception { - String ogDcSubjectChoices = configurationService.getProperty("choices.plugin.dc.subject"); - String ogDcSubjectAuthorityControlled = configurationService.getProperty("authority.controlled.dc.subject"); - configurationService.setProperty("choices.plugin.dc.subject", "SolrSubjectAuthority"); configurationService.setProperty("authority.controlled.dc.subject", @@ -326,14 +323,6 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe ) ) ); - - // Clean up configuration for the following tests - configurationService.setProperty("choices.plugin.dc.subject", - ogDcSubjectChoices); - configurationService.setProperty("authority.controlled.dc.subject", - ogDcSubjectAuthorityControlled); - - metadataAuthorityService.clearCache(); } @Test diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java index 5f11ff91f5..fd3bc1a351 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java @@ -188,9 +188,6 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest @Test public void discoverFacetsAuthorWithAuthorityWithSizeParameter() throws Exception { - String ogDcSubjectChoices = configurationService.getProperty("choices.plugin.dc.subject"); - String ogDcSubjectAuthorityControlled = configurationService.getProperty("authority.controlled.dc.subject"); - configurationService.setProperty("choices.plugin.dc.subject", "SolrSubjectAuthority"); configurationService.setProperty("authority.controlled.dc.subject", @@ -271,17 +268,9 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest // up in different items //These subjects are the most used ones. Only two show up because of the size. .andExpect(jsonPath("$._embedded.values", containsInAnyOrder( - FacetValueMatcher.entrySubject("History of religion", 3), - FacetValueMatcher.entrySubject("Church studies", 2) + FacetValueMatcher.entrySubject("History of religion", "VR110102", 3), + FacetValueMatcher.entrySubject("Church studies", "VR110103", 2) ))); - - // Clean up configuration for the following tests - configurationService.setProperty("choices.plugin.dc.subject", - ogDcSubjectChoices); - configurationService.setProperty("authority.controlled.dc.subject", - ogDcSubjectAuthorityControlled); - - metadataAuthorityService.clearCache(); } @Test diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/BrowseEntryResourceMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/BrowseEntryResourceMatcher.java index d2fcfbb4c7..ce728746df 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/BrowseEntryResourceMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/BrowseEntryResourceMatcher.java @@ -37,12 +37,8 @@ public class BrowseEntryResourceMatcher { public static Matcher matchBrowseEntry(String value, String authority, int expectedCount) { return allOf( - //Check core metadata (the JSON Path expression evaluates to a collection so we have to use contains) - hasJsonPath("$.value", is(value)), hasJsonPath("$.authority", is(authority)), - hasJsonPath("$.count", is(expectedCount)), - //Check links - matchItemLinks() + matchBrowseEntry(value, expectedCount) ); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java index b881e5974f..146bcbfacd 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java @@ -38,6 +38,14 @@ public class FacetValueMatcher { ); } + + public static Matcher entrySubject(String label, String authority, int count) { + return allOf( + hasJsonPath("$.authorityKey", is(authority)), + entrySubject(label, count) + ); + } + public static Matcher entryDateIssued() { return allOf( hasJsonPath("$.label", Matchers.notNullValue()), From afef66b1b8aed8427c4a1151990590e563d2ba25 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Tue, 9 Mar 2021 13:10:19 +0100 Subject: [PATCH 127/179] added tests that prove the correct links during the request with pagination information --- .../app/rest/CollectionRestRepositoryIT.java | 144 +++++++++++++++++- .../app/rest/CommunityRestRepositoryIT.java | 32 +++- .../app/rest/EntityTypeRestRepositoryIT.java | 60 ++++++++ .../dspace/app/rest/ItemRestRepositoryIT.java | 33 +++- .../rest/MetadataSchemaRestRepositoryIT.java | 74 +++++++++ .../rest/MetadatafieldRestRepositoryIT.java | 83 ++++++++++ .../app/rest/ScriptRestRepositoryIT.java | 39 ++++- .../SubmissionDefinitionsControllerIT.java | 51 +++++++ .../app/rest/SubmissionFormsControllerIT.java | 79 ++++++++++ 9 files changed, 583 insertions(+), 12 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionRestRepositoryIT.java index d966107340..fec59cc368 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionRestRepositoryIT.java @@ -251,7 +251,23 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes CollectionMatcher.matchCollectionEntrySpecificEmbedProjection(col2.getName(), col2.getID(), col2.getHandle()) ) - ))); + ))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/collections?"), + Matchers.containsString("page=0"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/collections?"), + Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/core/collections?"), + Matchers.containsString("page=1"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/collections?"), + Matchers.containsString("page=1"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$.page.size", is(1))) + .andExpect(jsonPath("$.page.totalElements", is(2))) + .andExpect(jsonPath("$.page.number", is(0))) + ; getClient().perform(get("/api/core/collections") .param("size", "1") @@ -269,7 +285,22 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes CollectionMatcher.matchCollectionEntrySpecificEmbedProjection(col1.getName(), col1.getID(), col1.getHandle()) ) - ))); + ))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/collections?"), + Matchers.containsString("page=0"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/core/collections?"), + Matchers.containsString("page=0"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/collections?"), + Matchers.containsString("page=1"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/collections?"), + Matchers.containsString("page=1"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$.page.size", is(1))) + .andExpect(jsonPath("$.page.totalElements", is(2))) + .andExpect(jsonPath("$.page.number", is(1))); } @@ -1869,6 +1900,18 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes CollectionMatcher.matchProperties(col2.getName(), col2.getID(), col2.getHandle()) ))) .andExpect(jsonPath("$._embedded.collections").value(Matchers.hasSize(2))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=3"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$.page.size", is(2))) .andExpect(jsonPath("$.page.totalPages", is(4))) .andExpect(jsonPath("$.page.number", is(0))) @@ -1884,6 +1927,21 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes CollectionMatcher.matchProperties(col4.getName(), col4.getID(), col4.getHandle()) ))) .andExpect(jsonPath("$._embedded.collections").value(Matchers.hasSize(2))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=2"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=3"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$.page.size", is(2))) .andExpect(jsonPath("$.page.totalPages", is(4))) .andExpect(jsonPath("$.page.number", is(1))) @@ -1899,6 +1957,21 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes CollectionMatcher.matchProperties(col6.getName(), col6.getID(), col6.getHandle()) ))) .andExpect(jsonPath("$._embedded.collections").value(Matchers.hasSize(2))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=2"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=3"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=3"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$.page.size", is(2))) .andExpect(jsonPath("$.page.totalPages", is(4))) .andExpect(jsonPath("$.page.number", is(2))) @@ -1915,6 +1988,21 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes CollectionMatcher.matchProperties(col6.getName(), col6.getID(), col6.getHandle()) ))) .andExpect(jsonPath("$._embedded.collections").value(Matchers.hasSize(3))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=1"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=2"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("page=2"), Matchers.containsString("size=3")))) .andExpect(jsonPath("$.page.size", is(3))) .andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.number", is(1))) @@ -1965,6 +2053,22 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes hasJsonPath("$.type", is("collection"))) )) .andExpect(jsonPath("$._embedded.collections").value(Matchers.hasSize(2))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("query=sample"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("query=sample"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("query=sample"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("query=sample"), + Matchers.containsString("page=2"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$.page.size", is(2))) .andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.number", is(0))) @@ -1980,6 +2084,26 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes hasJsonPath("$.type", is("collection"))) )) .andExpect(jsonPath("$._embedded.collections").value(Matchers.hasSize(2))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("query=sample"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("query=sample"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("query=sample"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("query=sample"), + Matchers.containsString("page=2"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("query=sample"), + Matchers.containsString("page=2"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$.page.size", is(2))) .andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.number", is(1))) @@ -1995,6 +2119,22 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes hasJsonPath("$.type", is("collection"))) )) .andExpect(jsonPath("$._embedded.collections").value(Matchers.hasSize(1))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("query=sample"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("query=sample"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("query=sample"), + Matchers.containsString("page=2"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/collections/search/findSubmitAuthorized?"), + Matchers.containsString("query=sample"), + Matchers.containsString("page=2"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$.page.size", is(2))) .andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.number", is(2))) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java index a157bd43c0..0ab5ec1597 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityRestRepositoryIT.java @@ -734,7 +734,22 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest child1.getHandle()) ) ))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities"))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/communities?"), + Matchers.containsString("page=0"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/communities?"), + Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/core/communities?"), + Matchers.containsString("page=1"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/communities?"), + Matchers.containsString("page=1"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$.page.size", is(1))) + .andExpect(jsonPath("$.page.totalPages", is(2))) + .andExpect(jsonPath("$.page.number", is(0))) + .andExpect(jsonPath("$.page.totalElements", is(2))) ; getClient().perform(get("/api/core/communities") @@ -754,7 +769,20 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest parentCommunity.getHandle()) ) ))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities"))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/communities?"), + Matchers.containsString("page=0"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/core/communities?"), + Matchers.containsString("page=0"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/communities?"), + Matchers.containsString("page=1"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/communities?"), + Matchers.containsString("page=1"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$.page.number", is(1))) + .andExpect(jsonPath("$.page.totalPages", is(2))) .andExpect(jsonPath("$.page.size", is(1))) .andExpect(jsonPath("$.page.totalElements", is(2))) ; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/EntityTypeRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/EntityTypeRestRepositoryIT.java index 5a8706cff8..0f6060c011 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/EntityTypeRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/EntityTypeRestRepositoryIT.java @@ -18,6 +18,7 @@ import org.dspace.app.rest.matcher.EntityTypeMatcher; import org.dspace.app.rest.test.AbstractEntityIntegrationTest; import org.dspace.content.EntityType; import org.dspace.content.service.EntityTypeService; +import org.hamcrest.Matchers; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -108,4 +109,63 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { getClient().perform(get("/api/core/entitytypes/" + 5555)) .andExpect(status().isNotFound()); } + + @Test + public void findAllPaginationTest() throws Exception { + getClient().perform(get("/api/core/entitytypes") + .param("page", "0") + .param("size", "3")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Publication")), + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Person")), + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Project")) + ))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/entitytypes?"), + Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/entitytypes?"), + Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/core/entitytypes?"), + Matchers.containsString("page=1"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/entitytypes?"), + Matchers.containsString("page=2"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$.page.size", is(3))) + .andExpect(jsonPath("$.page.totalElements", is(7))) + .andExpect(jsonPath("$.page.totalPages", is(3))) + .andExpect(jsonPath("$.page.number", is(0))); + + getClient().perform(get("/api/core/entitytypes") + .param("page", "1") + .param("size", "3")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "OrgUnit")), + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Journal")), + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "JournalVolume")) + ))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/entitytypes?"), + Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/core/entitytypes?"), + Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/entitytypes?"), + Matchers.containsString("page=1"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/core/entitytypes?"), + Matchers.containsString("page=2"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/entitytypes?"), + Matchers.containsString("page=2"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$.page.size", is(3))) + .andExpect(jsonPath("$.page.totalElements", is(7))) + .andExpect(jsonPath("$.page.totalPages", is(3))) + .andExpect(jsonPath("$.page.number", is(1))); + } + } \ No newline at end of file diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java index 9e53afc1b4..fd2b361da2 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java @@ -211,8 +211,21 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { "Public item 3", "2016-02-13") ) ))) - .andExpect(jsonPath("$._links.self.href", - Matchers.containsString("/api/core/items"))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/items?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/items?"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/core/items?"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/items?"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$.page.size", is(2))) + .andExpect(jsonPath("$.page.totalPages", is(2))) + .andExpect(jsonPath("$.page.number", is(0))) + .andExpect(jsonPath("$.page.totalElements", is(3))); ; getClient(token).perform(get("/api/core/items") @@ -231,9 +244,21 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { "Public item 2", "2016-02-13") ) ))) - .andExpect(jsonPath("$._links.self.href", - Matchers.containsString("/api/core/items"))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/items?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/core/items?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/items?"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/items?"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$.page.size", is(2))) + .andExpect(jsonPath("$.page.number", is(1))) + .andExpect(jsonPath("$.page.totalPages", is(2))) .andExpect(jsonPath("$.page.totalElements", is(3))) ; } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java index 4a094d7dc9..76238d02c0 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java @@ -268,4 +268,78 @@ public class MetadataSchemaRestRepositoryIT extends AbstractControllerIntegratio .matchEntry(TEST_NAME, TEST_NAMESPACE))); } + @Test + public void findAllPaginationTest() throws Exception { + + getClient().perform(get("/api/core/metadataschemas") + .param("size", "6") + .param("page", "0")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.metadataschemas", Matchers.hasItem(matchEntry()))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/metadataschemas?"), + Matchers.containsString("page=0"), Matchers.containsString("size=6")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/metadataschemas?"), + Matchers.containsString("page=0"), Matchers.containsString("size=6")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/core/metadataschemas?"), + Matchers.containsString("page=1"), Matchers.containsString("size=6")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/metadataschemas?"), + Matchers.containsString("page=2"), Matchers.containsString("size=6")))) + .andExpect(jsonPath("$.page.totalElements", is(16))) + .andExpect(jsonPath("$.page.totalPages", is(3))) + .andExpect(jsonPath("$.page.size", is(6))); + + getClient().perform(get("/api/core/metadataschemas") + .param("size", "6") + .param("page", "1")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.metadataschemas", Matchers.hasItem(matchEntry()))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/metadataschemas?"), + Matchers.containsString("page=0"), Matchers.containsString("size=6")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/core/metadataschemas?"), + Matchers.containsString("page=0"), Matchers.containsString("size=6")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/metadataschemas?"), + Matchers.containsString("page=1"), Matchers.containsString("size=6")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/core/metadataschemas?"), + Matchers.containsString("page=2"), Matchers.containsString("size=6")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/metadataschemas?"), + Matchers.containsString("page=2"), Matchers.containsString("size=6")))) + .andExpect(jsonPath("$.page.totalElements", is(16))) + .andExpect(jsonPath("$.page.totalPages", is(3))) + .andExpect(jsonPath("$.page.size", is(6))); + + getClient().perform(get("/api/core/metadataschemas") + .param("size", "6") + .param("page", "2")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.metadataschemas", Matchers.hasItem(matchEntry()))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/metadataschemas?"), + Matchers.containsString("page=0"), Matchers.containsString("size=6")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/core/metadataschemas?"), + Matchers.containsString("page=1"), Matchers.containsString("size=6")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/metadataschemas?"), + Matchers.containsString("page=2"), Matchers.containsString("size=6")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/metadataschemas?"), + Matchers.containsString("page=2"), Matchers.containsString("size=6")))) + .andExpect(jsonPath("$.page.totalElements", is(16))) + .andExpect(jsonPath("$.page.totalPages", is(3))) + .andExpect(jsonPath("$.page.size", is(6))); + + } + } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadatafieldRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadatafieldRestRepositoryIT.java index 49b9045aac..259a6e0e0b 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadatafieldRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadatafieldRestRepositoryIT.java @@ -929,5 +929,88 @@ public class MetadatafieldRestRepositoryIT extends AbstractControllerIntegration } + @Test + public void findAllPaginationTest() throws Exception { + getClient().perform(get("/api/core/metadatafields") + .param("size", "3") + .param("page", "0")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItems( + MetadataFieldMatcher.matchMetadataFieldByKeys("creativework","datePublished", null), + MetadataFieldMatcher.matchMetadataFieldByKeys("creativework", "editor", null), + MetadataFieldMatcher.matchMetadataFieldByKeys("creativework", "keywords", null) + ))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/metadatafields?"), + Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/metadatafields?"), + Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/core/metadatafields?"), + Matchers.containsString("page=1"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/metadatafields?"), + Matchers.containsString("page=63"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$.page.totalElements", is(192))) + .andExpect(jsonPath("$.page.totalPages", is(64))) + .andExpect(jsonPath("$.page.size", is(3))); + + getClient().perform(get("/api/core/metadatafields") + .param("size", "3") + .param("page", "1")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItems( + MetadataFieldMatcher.matchMetadataFieldByKeys("creativework","publisher", null), + MetadataFieldMatcher.matchMetadataFieldByKeys("creativeworkseries", "issn", null), + MetadataFieldMatcher.matchMetadataFieldByKeys("dc", "contributor", null) + ))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/metadatafields?"), + Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/core/metadatafields?"), + Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/metadatafields?"), + Matchers.containsString("page=1"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/core/metadatafields?"), + Matchers.containsString("page=2"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/metadatafields?"), + Matchers.containsString("page=63"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$.page.totalElements", is(192))) + .andExpect(jsonPath("$.page.totalPages", is(64))) + .andExpect(jsonPath("$.page.size", is(3))); + + getClient().perform(get("/api/core/metadatafields") + .param("size", "3") + .param("page", "63")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItems( + MetadataFieldMatcher.matchMetadataFieldByKeys("relation","isVolumeOfJournal", null), + MetadataFieldMatcher.matchMetadataFieldByKeys("relationship", "type", null), + MetadataFieldMatcher.matchMetadataFieldByKeys("workflow", "score", null) + ))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/core/metadatafields?"), + Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/core/metadatafields?"), + Matchers.containsString("page=62"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/core/metadatafields?"), + Matchers.containsString("page=63"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/core/metadatafields?"), + Matchers.containsString("page=63"), Matchers.containsString("size=3")))) + .andExpect(jsonPath("$.page.totalElements", is(192))) + .andExpect(jsonPath("$.page.totalPages", is(64))) + .andExpect(jsonPath("$.page.size", is(3))); + } } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ScriptRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ScriptRestRepositoryIT.java index 7782b21020..16013fec17 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ScriptRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ScriptRestRepositoryIT.java @@ -127,8 +127,22 @@ public class ScriptRestRepositoryIT extends AbstractControllerIntegrationTest { ScriptMatcher.matchScript(scriptConfigurations.get(2).getName(), scriptConfigurations.get(2).getDescription()) ))) - .andExpect(jsonPath("$.page", - is(PageMatcher.pageEntry(0, 1)))); + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/system/scripts?"), + Matchers.containsString("page=0"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/system/scripts?"), + Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/system/scripts?"), + Matchers.containsString("page=1"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/system/scripts?"), + Matchers.containsString("page=6"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$.page.size", is(1))) + .andExpect(jsonPath("$.page.number", is(0))) + .andExpect(jsonPath("$.page.totalPages", is(7))) + .andExpect(jsonPath("$.page.totalElements", is(7))); getClient(token).perform(get("/api/system/scripts").param("size", "1").param("page", "1")) @@ -141,8 +155,25 @@ public class ScriptRestRepositoryIT extends AbstractControllerIntegrationTest { ScriptMatcher.matchScript(scriptConfigurations.get(0).getName(), scriptConfigurations.get(0).getDescription()) )))) - .andExpect(jsonPath("$.page", - is(PageMatcher.pageEntry(1, 1)))); + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/system/scripts?"), + Matchers.containsString("page=0"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/system/scripts?"), + Matchers.containsString("page=0"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/system/scripts?"), + Matchers.containsString("page=1"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/system/scripts?"), + Matchers.containsString("page=2"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/system/scripts?"), + Matchers.containsString("page=6"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$.page.size", is(1))) + .andExpect(jsonPath("$.page.number", is(1))) + .andExpect(jsonPath("$.page.totalPages", is(7))) + .andExpect(jsonPath("$.page.totalElements", is(7))); } @Test diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionDefinitionsControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionDefinitionsControllerIT.java index e642336b1c..7bda8134ac 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionDefinitionsControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionDefinitionsControllerIT.java @@ -222,4 +222,55 @@ public class SubmissionDefinitionsControllerIT extends AbstractControllerIntegra )))) ; } + + @Test + public void findAllPaginationTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/config/submissiondefinitions") + .param("size", "1") + .param("page", "0")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.submissiondefinitions[0].id", is("traditional"))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/config/submissiondefinitions?"), + Matchers.containsString("page=0"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/config/submissiondefinitions?"), + Matchers.containsString("page=0"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/config/submissiondefinitions?"), + Matchers.containsString("page=1"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/config/submissiondefinitions?"), + Matchers.containsString("page=1"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$.page.size", is(1))) + .andExpect(jsonPath("$.page.totalElements", is(2))) + .andExpect(jsonPath("$.page.totalPages", is(2))) + .andExpect(jsonPath("$.page.number", is(0))); + + getClient(tokenAdmin).perform(get("/api/config/submissiondefinitions") + .param("size", "1") + .param("page", "1")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.submissiondefinitions[0].id", is("languagetestprocess"))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/config/submissiondefinitions?"), + Matchers.containsString("page=0"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/config/submissiondefinitions?"), + Matchers.containsString("page=0"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/config/submissiondefinitions?"), + Matchers.containsString("page=1"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/config/submissiondefinitions?"), + Matchers.containsString("page=1"), Matchers.containsString("size=1")))) + .andExpect(jsonPath("$.page.size", is(1))) + .andExpect(jsonPath("$.page.totalElements", is(2))) + .andExpect(jsonPath("$.page.totalPages", is(2))) + .andExpect(jsonPath("$.page.number", is(1))); + } + } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionFormsControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionFormsControllerIT.java index f89ab3869d..dcf2253d47 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionFormsControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionFormsControllerIT.java @@ -641,4 +641,83 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe pluginService.clearNamedPluginClasses(); cas.clearCache(); } + + @Test + public void findAllPaginationTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/config/submissionforms") + .param("size", "2") + .param("page", "0")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.submissionforms[0].id", is("bitstream-metadata"))) + .andExpect(jsonPath("$._embedded.submissionforms[1].id", is("journalVolumeStep"))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/config/submissionforms?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/config/submissionforms?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/config/submissionforms?"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/config/submissionforms?"), + Matchers.containsString("page=2"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$.page.size", is(2))) + .andExpect(jsonPath("$.page.totalElements", equalTo(6))) + .andExpect(jsonPath("$.page.totalPages", equalTo(3))) + .andExpect(jsonPath("$.page.number", is(0))); + + getClient(tokenAdmin).perform(get("/api/config/submissionforms") + .param("size", "2") + .param("page", "1")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.submissionforms[0].id", is("languagetest"))) + .andExpect(jsonPath("$._embedded.submissionforms[1].id", is("traditionalpagetwo"))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/config/submissionforms?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/config/submissionforms?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/config/submissionforms?"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("/api/config/submissionforms?"), + Matchers.containsString("page=2"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/config/submissionforms?"), + Matchers.containsString("page=2"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$.page.size", is(2))) + .andExpect(jsonPath("$.page.totalElements", equalTo(6))) + .andExpect(jsonPath("$.page.totalPages", equalTo(3))) + .andExpect(jsonPath("$.page.number", is(1))); + + getClient(tokenAdmin).perform(get("/api/config/submissionforms") + .param("size", "2") + .param("page", "2")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.submissionforms[0].id", is("sampleauthority"))) + .andExpect(jsonPath("$._embedded.submissionforms[1].id", is("traditionalpageone"))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("/api/config/submissionforms?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("/api/config/submissionforms?"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("/api/config/submissionforms?"), + Matchers.containsString("page=2"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("/api/config/submissionforms?"), + Matchers.containsString("page=2"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$.page.size", is(2))) + .andExpect(jsonPath("$.page.totalElements", equalTo(6))) + .andExpect(jsonPath("$.page.totalPages", equalTo(3))) + .andExpect(jsonPath("$.page.number", is(2))); + } } From b153194348ccc122dc9738bdc83c2c804d0ee9cb Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Tue, 9 Mar 2021 13:16:44 +0100 Subject: [PATCH 128/179] fixed bug that hided pagination information in the self link --- .../org/dspace/app/rest/RestResourceController.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java index 2a1f6fbe57..1904c7e0fc 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java @@ -11,7 +11,6 @@ import static org.dspace.app.rest.utils.RegexUtils.REGEX_REQUESTMAPPING_IDENTIFI import static org.dspace.app.rest.utils.RegexUtils.REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG; import static org.dspace.app.rest.utils.RegexUtils.REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; -import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; import java.io.FileNotFoundException; import java.io.IOException; @@ -916,14 +915,12 @@ public class RestResourceController implements InitializingBean { @RequestMapping(method = RequestMethod.GET) @SuppressWarnings("unchecked") public PagedModel> findAll(@PathVariable String apiCategory, - @PathVariable String model, - Pageable page, - PagedResourcesAssembler assembler, - HttpServletResponse response) { + @PathVariable String model, Pageable page, PagedResourcesAssembler assembler, HttpServletResponse response, + @RequestParam MultiValueMap parameters) { + + String encodedParameterString = getEncodedParameterStringFromRequestParams(parameters); DSpaceRestRepository repository = utils.getResourceRepository(apiCategory, model); - Link link = linkTo(methodOn(this.getClass(), apiCategory, model).findAll(apiCategory, model, - page, assembler, response)) - .withSelfRel(); + Link link = linkTo(this.getClass(), apiCategory, model).slash(encodedParameterString).withSelfRel(); Page> resources; try { From 65c84f0554e6ed39e8e8e2a95273af5efa846181 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Tue, 9 Mar 2021 16:30:04 +0100 Subject: [PATCH 129/179] added check to model plural name for search methods --- .../main/java/org/dspace/app/rest/RestResourceController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java index 2a1f6fbe57..568deb10c6 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java @@ -951,6 +951,7 @@ public class RestResourceController implements InitializingBean { @RequestMapping(method = RequestMethod.GET, value = "/search") public RepresentationModel listSearchMethods(@PathVariable String apiCategory, @PathVariable String model) { + checkModelPluralForm(apiCategory, model); RepresentationModel root = new RepresentationModel(); DSpaceRestRepository repository = utils.getResourceRepository(apiCategory, model); From e6576e07cda8031c3f0a9f3a5bf20e5ec9a43f2d Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Tue, 9 Mar 2021 17:33:18 +0100 Subject: [PATCH 130/179] added tests to prove right functionalicy of root search end points --- .../rest/ResourcePolicyRestRepositoryIT.java | 20 ++++++++++++ .../SubmissionCCLicenseUrlRepositoryIT.java | 17 ++++++++++ .../app/rest/TaskRestRepositoriesIT.java | 32 +++++++++++++++++++ .../app/rest/VocabularyEntryDetailsIT.java | 15 +++++++++ 4 files changed, 84 insertions(+) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResourcePolicyRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResourcePolicyRestRepositoryIT.java index e5020f601f..777d116cdd 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResourcePolicyRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResourcePolicyRestRepositoryIT.java @@ -2574,4 +2574,24 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio .andExpect(jsonPath("$.page.totalPages", is(4))) .andExpect(jsonPath("$.page.totalElements", is(4))); } + + @Test + public void resourcepolicySerchMethodWithSingleModelTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/authz/resourcepolicy/search")) + .andExpect(status().isNotFound()); + } + + @Test + public void resourcepolicySerchMethodWithPluralModelTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/authz/resourcepolicies/search")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._links.eperson.href", Matchers.allOf( + Matchers.containsString("/api/authz/resourcepolicies/search/eperson")))) + .andExpect(jsonPath("$._links.group.href", Matchers.allOf( + Matchers.containsString("/api/authz/resourcepolicies/search/group")))) + .andExpect(jsonPath("$._links.resource.href", Matchers.allOf( + Matchers.containsString("/api/authz/resourcepolicies/search/resource")))); + } } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionCCLicenseUrlRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionCCLicenseUrlRepositoryIT.java index 84fe06ce19..bea607a86d 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionCCLicenseUrlRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionCCLicenseUrlRepositoryIT.java @@ -14,6 +14,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.hamcrest.Matchers; import org.junit.Test; /** @@ -96,4 +97,20 @@ public class SubmissionCCLicenseUrlRepositoryIT extends AbstractControllerIntegr .andExpect(status().isUnauthorized()); } + + @Test + public void submissionCCLicenseUrlSerchMethodWithSingleModelTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/config/submissioncclicenseUrl/search")) + .andExpect(status().isNotFound()); + } + + @Test + public void submissionCCLicenseUrlSerchMethodWithPluralModelTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/config/submissioncclicenseUrls/search")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._links.rightsByQuestions.href", Matchers.allOf(Matchers + .containsString("/api/config/submissioncclicenseUrls/search/rightsByQuestions")))); + } } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java index a7813601ec..9f8169e495 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java @@ -3092,4 +3092,36 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { bibtex.close(); } + @Test + public void poolTaskSerchMethodWithSingleModelTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/workflow/pooltask/search")) + .andExpect(status().isNotFound()); + } + + @Test + public void claimedtaskSerchMethodWithSingleModelTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/workflow/claimedtask/search")) + .andExpect(status().isNotFound()); + } + + @Test + public void poolTaskSerchMethodWithPluralModelTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/workflow/pooltasks/search")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._links.findByUser.href", Matchers.allOf( + Matchers.containsString("/api/workflow/pooltasks/search/findByUser")))); + } + + @Test + public void claimedtaskSerchMethodWithPluralModelTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/workflow/claimedtasks/search")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._links.findByUser.href", Matchers.allOf( + Matchers.containsString("/api/workflow/claimedtasks/search/findByUser")))); + } + } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/VocabularyEntryDetailsIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/VocabularyEntryDetailsIT.java index e5eab1aa98..4962e1aef2 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/VocabularyEntryDetailsIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/VocabularyEntryDetailsIT.java @@ -439,4 +439,19 @@ public class VocabularyEntryDetailsIT extends AbstractControllerIntegrationTest ); } + @Test + public void vocabularyEntryDetailSerchMethodWithSingleModelTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/submission/vocabularyEntryDetail/search")) + .andExpect(status().isNotFound()); + } + + @Test + public void vocabularyEntryDetailSerchMethodWithPluralModelTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/submission/vocabularyEntryDetails/search")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._links.top.href", Matchers.allOf( + Matchers.containsString("/api/submission/vocabularyEntryDetails/search/top")))); + } } From 559b267ca22b82c84a3fa7ec4742bf1b5a302cea Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Wed, 10 Mar 2021 10:44:01 +0100 Subject: [PATCH 131/179] changed single name to plural name on search methods of HAL links --- .../rest/SubmissionCCLicenseUrlRepository.java | 4 ++-- .../dspace/app/rest/model/ClaimedTaskRest.java | 1 + .../org/dspace/app/rest/model/PoolTaskRest.java | 1 + .../dspace/app/rest/model/ResourcePolicyRest.java | 1 + .../rest/model/VocabularyEntryDetailsRest.java | 1 + .../repository/ClaimedTaskRestRepository.java | 4 ++-- .../rest/repository/PoolTaskRestRepository.java | 4 ++-- .../repository/ResourcePolicyRestRepository.java | 4 ++-- .../VocabularyEntryDetailsRestRepository.java | 6 ++---- .../app/rest/ResourcePolicyRestRepositoryIT.java | 4 ++-- .../rest/SubmissionCCLicenseUrlRepositoryIT.java | 15 +++++++++++++++ .../app/rest/WorkflowItemRestRepositoryIT.java | 8 ++++---- 12 files changed, 35 insertions(+), 18 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/SubmissionCCLicenseUrlRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/SubmissionCCLicenseUrlRepository.java index 957484319c..78e71d91fd 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/SubmissionCCLicenseUrlRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/SubmissionCCLicenseUrlRepository.java @@ -133,8 +133,8 @@ public class SubmissionCCLicenseUrlRepository extends DSpaceRestRepository { public static final String NAME = "claimedtask"; + public static final String PLURAL_NAME = "claimedtasks"; public static final String CATEGORY = RestAddressableModel.WORKFLOW; public static final String STEP = "step"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/PoolTaskRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/PoolTaskRest.java index b3dedd23b9..c32c2c9578 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/PoolTaskRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/PoolTaskRest.java @@ -24,6 +24,7 @@ import org.dspace.xmlworkflow.storedcomponents.PoolTask; }) public class PoolTaskRest extends BaseObjectRest { public static final String NAME = "pooltask"; + public static final String PLURAL_NAME = "pooltasks"; public static final String CATEGORY = RestAddressableModel.WORKFLOW; public static final String STEP = "step"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ResourcePolicyRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ResourcePolicyRest.java index 656d9049fa..a75c17b136 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ResourcePolicyRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ResourcePolicyRest.java @@ -24,6 +24,7 @@ import org.dspace.app.rest.RestResourceController; public class ResourcePolicyRest extends BaseObjectRest { public static final String NAME = "resourcepolicy"; + public static final String PLURAL_NAME = "resourcepolicies"; public static final String CATEGORY = RestAddressableModel.AUTHORIZATION; private String name; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyEntryDetailsRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyEntryDetailsRest.java index 42644c8c85..30e5eb71cb 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyEntryDetailsRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyEntryDetailsRest.java @@ -22,6 +22,7 @@ import org.dspace.app.rest.RestResourceController; @LinkRest(name = VocabularyEntryDetailsRest.CHILDREN, method = "getChildren") }) public class VocabularyEntryDetailsRest extends BaseObjectRest { + public static final String PLURAL_NAME = "vocabularyEntryDetails"; public static final String NAME = "vocabularyEntryDetail"; public static final String PARENT = "parent"; public static final String CHILDREN = "children"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java index bc71290c1c..a1f8f78f29 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClaimedTaskRestRepository.java @@ -200,7 +200,7 @@ public class ClaimedTaskRestRepository extends DSpaceRestRepository Date: Thu, 11 Mar 2021 10:28:47 +0100 Subject: [PATCH 132/179] added test that proves delete of solr record --- .../org/dspace/discovery/DiscoveryIT.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java b/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java index 05ff5ae41a..f49d83498b 100644 --- a/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java +++ b/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java @@ -19,11 +19,13 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.builder.ClaimedTaskBuilder; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; +import org.dspace.builder.ItemBuilder; import org.dspace.builder.PoolTaskBuilder; import org.dspace.builder.WorkflowItemBuilder; import org.dspace.builder.WorkspaceItemBuilder; import org.dspace.content.Collection; import org.dspace.content.Community; +import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.ItemService; @@ -238,6 +240,39 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase { assertSearchQuery(IndexableItem.TYPE, 1); } + @Test + public void solrRecordAfterDeleteTest() throws Exception { + context.turnOffAuthorisationSystem(); + Community community = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection col = CollectionBuilder.createCollection(context, community) + .withName("Collection") + .build(); + + Item item1 = ItemBuilder.createItem(context, col) + .withTitle("Publication 1") + .build(); + + Item item2 = ItemBuilder.createItem(context, col) + .withTitle("Publication 2") + .build(); + + context.restoreAuthSystemState(); + + // we start with 2 items + assertSearchQuery(IndexableItem.TYPE, 2); + // simulate the delete of item2 + deleteItem(item2); + // now we should have 1 item + assertSearchQuery(IndexableItem.TYPE, 1); + // simulate the delete of item1 + deleteItem(item1); + // now we should have 0 item + assertSearchQuery(IndexableItem.TYPE, 0); + + } + private void assertSearchQuery(String resourceType, int size) throws SearchServiceException { DiscoverQuery discoverQuery = new DiscoverQuery(); discoverQuery.setQuery("*:*"); @@ -259,6 +294,15 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase { context.restoreAuthSystemState(); } + private void deleteItem(Item item) throws SQLException, AuthorizeException, IOException, SearchServiceException { + context.turnOffAuthorisationSystem(); + item = context.reloadEntity(item); + itemService.delete(context, item); + context.commit(); + indexer.commit(); + context.restoreAuthSystemState(); + } + private void deleteSubmission(WorkspaceItem anotherWorkspaceItem) throws SQLException, AuthorizeException, IOException, SearchServiceException { context.turnOffAuthorisationSystem(); From 66a8b1c7df0ecdba4f9ea61d48f8ec6fa811d1a6 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Thu, 11 Mar 2021 10:47:35 +0100 Subject: [PATCH 133/179] added fix that able to delete solr record --- .../java/org/dspace/discovery/IndexEventConsumer.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/discovery/IndexEventConsumer.java b/dspace-api/src/main/java/org/dspace/discovery/IndexEventConsumer.java index 620d29c45d..6e008b15eb 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/IndexEventConsumer.java +++ b/dspace-api/src/main/java/org/dspace/discovery/IndexEventConsumer.java @@ -138,8 +138,9 @@ public class IndexEventConsumer implements Consumer { // became directly an item without giving us the chance to retrieve a // workflowitem... so we need to force the unindex of all the related data // before to index it again to be sure to don't leave any zombie in solr - String detail = - Constants.typeText[event.getSubjectType()] + "-" + event.getSubjectID().toString(); + IndexFactory indexableObjectService = IndexObjectFactoryFactory.getInstance() + .getIndexFactoryByType(Constants.typeText[event.getSubjectType()]); + String detail = indexableObjectService.getType() + "-" + event.getSubjectID().toString(); uniqueIdsToDelete.add(detail); } objectsToUpdate.addAll(indexObjectServiceFactory.getIndexableObjects(ctx, subject)); @@ -163,7 +164,9 @@ public class IndexEventConsumer implements Consumer { if (event.getSubjectType() == -1 || event.getSubjectID() == null) { log.warn("got null subject type and/or ID on DELETE event, skipping it."); } else { - String detail = Constants.typeText[event.getSubjectType()] + "-" + event.getSubjectID().toString(); + IndexFactory indexableObjectService = IndexObjectFactoryFactory.getInstance() + .getIndexFactoryByType(Constants.typeText[event.getSubjectType()]); + String detail = indexableObjectService.getType() + "-" + event.getSubjectID().toString(); log.debug("consume() adding event to delete queue: " + event.toString()); uniqueIdsToDelete.add(detail); } From a49ebf4f38e160a0f30bc0f6466164f61d4c20c1 Mon Sep 17 00:00:00 2001 From: j4bbi Date: Thu, 11 Mar 2021 10:28:52 +0000 Subject: [PATCH 134/179] Update Commons Pool2 dep to 2.9.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1981d80b03..6000cecd7d 100644 --- a/pom.xml +++ b/pom.xml @@ -1343,7 +1343,7 @@ org.apache.commons commons-pool2 - 2.4.2 + 2.9.0 commons-validator From 75e3369d39467fc3e5e77536d93100bb5ac24019 Mon Sep 17 00:00:00 2001 From: Hrafn Malmquist Date: Fri, 12 Mar 2021 09:59:45 +0000 Subject: [PATCH 135/179] Clarify removeAbandoned, add reference to core-hibernate.xml --- dspace/config/dspace.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index b097b54b70..eb1e571ee1 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -75,6 +75,7 @@ db.schema = public ## Database Connection pool parameters # DSpace wraps around the Apache Commons DBCP2 component, to read about its configuration # see: https://commons.apache.org/proper/commons-dbcp/configuration.html +# look at DSPACE/config/spring/api/core-hibernate.xml for more options # Maximum number of active DB connections in pool (-1 = unlimited) # (default = 30) @@ -100,7 +101,7 @@ db.initialsize = 0 # (default = -1) db.maxconnlifetime = -1 -# Remove abandoned connections. +# Remove abandoned connections. This is documented under "removeAbandonedOnBorrow" in DBCP2. # (default = false) db.removeabandoned = false From f52cc59dde3d7269efc0447b5c896c16af9dbd81 Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Tue, 16 Mar 2021 11:19:43 +0100 Subject: [PATCH 136/179] TEST PoolTask/ClaimedTask indexing --- .../indexobject/InprogressSubmissionIndexFactoryImpl.java | 7 +++++-- .../indexobject/WorkflowItemIndexFactoryImpl.java | 8 ++++---- .../indexobject/WorkspaceItemIndexFactoryImpl.java | 8 ++++---- .../factory/InprogressSubmissionIndexFactory.java | 5 +++-- .../test/java/org/dspace/builder/ClaimedTaskBuilder.java | 4 ++-- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/InprogressSubmissionIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/InprogressSubmissionIndexFactoryImpl.java index 4109d11021..68b26a61da 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/InprogressSubmissionIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/InprogressSubmissionIndexFactoryImpl.java @@ -15,6 +15,7 @@ import org.apache.solr.common.SolrInputDocument; import org.dspace.content.InProgressSubmission; import org.dspace.content.Item; import org.dspace.core.Context; +import org.dspace.discovery.SearchUtils; import org.dspace.discovery.indexobject.factory.CollectionIndexFactory; import org.dspace.discovery.indexobject.factory.InprogressSubmissionIndexFactory; import org.dspace.discovery.indexobject.factory.ItemIndexFactory; @@ -47,7 +48,7 @@ public abstract class InprogressSubmissionIndexFactoryImpl @Override public void storeInprogressItemFields(Context context, SolrInputDocument doc, - InProgressSubmission inProgressSubmission) throws SQLException { + InProgressSubmission inProgressSubmission) throws SQLException, IOException { final Item item = inProgressSubmission.getItem(); doc.addField("lastModified", SolrUtils.getDateFormatter().format(item.getLastModified())); EPerson submitter = inProgressSubmission.getSubmitter(); @@ -61,6 +62,8 @@ public abstract class InprogressSubmissionIndexFactoryImpl // get the location string (for searching by collection & community) List locations = indexableCollectionService. getCollectionLocations(context, inProgressSubmission.getCollection()); + + indexableItemService.addDiscoveryFields(doc, context, item, SearchUtils.getAllDiscoveryConfigurations(item)); indexableCollectionService.storeCommunityCollectionLocations(doc, locations); } -} \ No newline at end of file +} diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkflowItemIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkflowItemIndexFactoryImpl.java index 46439f3919..9e2f7ba30c 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkflowItemIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkflowItemIndexFactoryImpl.java @@ -76,9 +76,9 @@ public class WorkflowItemIndexFactoryImpl final XmlWorkflowItem workflowItem = indexableObject.getIndexedObject(); final Item item = workflowItem.getItem(); // Add the item metadata as configured - List discoveryConfigurations = SearchUtils - .getAllDiscoveryConfigurations(workflowItem); - indexableItemService.addDiscoveryFields(doc, context, item, discoveryConfigurations); +// List discoveryConfigurations = SearchUtils +// .getAllDiscoveryConfigurations(workflowItem); +// indexableItemService.addDiscoveryFields(doc, context, item, discoveryConfigurations); String acvalue = DSpaceServicesFactory.getInstance().getConfigurationService() .getProperty("discovery.facet.namedtype.workflow.item"); @@ -118,4 +118,4 @@ public class WorkflowItemIndexFactoryImpl final XmlWorkflowItem xmlWorkflowItem = workflowItemService.find(context, Integer.parseInt(id)); return xmlWorkflowItem == null ? Optional.empty() : Optional.of(new IndexableWorkflowItem(xmlWorkflowItem)); } -} \ No newline at end of file +} diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkspaceItemIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkspaceItemIndexFactoryImpl.java index 08cb484497..2e68a72627 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkspaceItemIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkspaceItemIndexFactoryImpl.java @@ -74,9 +74,9 @@ public class WorkspaceItemIndexFactoryImpl final WorkspaceItem inProgressSubmission = indexableObject.getIndexedObject(); // Add the item metadata as configured - List discoveryConfigurations = SearchUtils - .getAllDiscoveryConfigurations(inProgressSubmission); - indexableItemService.addDiscoveryFields(doc, context, inProgressSubmission.getItem(), discoveryConfigurations); +// List discoveryConfigurations = SearchUtils +// .getAllDiscoveryConfigurations(inProgressSubmission); +// indexableItemService.addDiscoveryFields(doc, context, inProgressSubmission.getItem(), discoveryConfigurations); return doc; } @@ -96,4 +96,4 @@ public class WorkspaceItemIndexFactoryImpl final WorkspaceItem workspaceItem = workspaceItemService.find(context, Integer.parseInt(id)); return workspaceItem == null ? Optional.empty() : Optional.of(new IndexableWorkspaceItem(workspaceItem)); } -} \ No newline at end of file +} diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/InprogressSubmissionIndexFactory.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/InprogressSubmissionIndexFactory.java index b858b54280..79c530dc6d 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/InprogressSubmissionIndexFactory.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/factory/InprogressSubmissionIndexFactory.java @@ -7,6 +7,7 @@ */ package org.dspace.discovery.indexobject.factory; +import java.io.IOException; import java.sql.SQLException; import org.apache.solr.common.SolrInputDocument; @@ -31,5 +32,5 @@ public interface InprogressSubmissionIndexFactory Date: Tue, 16 Mar 2021 12:20:31 +0100 Subject: [PATCH 137/179] 77582: Add HandleService#formatHandle to strip prefixes from handle --- .../org/dspace/handle/HandleServiceImpl.java | 43 +++++++++++++++++++ .../dspace/handle/service/HandleService.java | 11 +++++ .../identifier/HandleIdentifierProvider.java | 28 +----------- .../VersionedHandleIdentifierProvider.java | 29 +------------ ...dentifierProviderWithCanonicalHandles.java | 28 +----------- .../app/rest/IdentifierRestControllerIT.java | 30 +++++++++++++ 6 files changed, 89 insertions(+), 80 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/handle/HandleServiceImpl.java b/dspace-api/src/main/java/org/dspace/handle/HandleServiceImpl.java index 4c5138cf35..0deb1e9d76 100644 --- a/dspace-api/src/main/java/org/dspace/handle/HandleServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/handle/HandleServiceImpl.java @@ -10,6 +10,8 @@ package org.dspace.handle; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -57,6 +59,13 @@ public class HandleServiceImpl implements HandleService { @Autowired protected SiteService siteService; + private static final Pattern[] IDENTIFIER_PATTERNS = { + Pattern.compile("^hdl:(.*)$"), + Pattern.compile("^info:hdl/(.*)$"), + Pattern.compile("^https?://hdl\\.handle\\.net/(.*)$"), + Pattern.compile("^https?://.+/handle/(.*)$") + }; + /** * Public Constructor */ @@ -376,4 +385,38 @@ public class HandleServiceImpl implements HandleService { public int countTotal(Context context) throws SQLException { return handleDAO.countRows(context); } + + public String formatHandle(String identifier) { + if (identifier == null) { + return null; + } + if (identifier.startsWith(getPrefix() + "/")) { + // prefix is the equivalent of 123456789 in 123456789/???; don't strip + return identifier; + } + + String canonicalPrefix = configurationService.getProperty("handle.canonical.prefix"); + if (identifier.startsWith(canonicalPrefix + "/")) { + // prefix is the equivalent of https://hdl.handle.net/ in https://hdl.handle.net/123456789/???; strip + return StringUtils.stripStart(identifier, canonicalPrefix); + } + + for (Pattern pattern : IDENTIFIER_PATTERNS) { + Matcher matcher = pattern.matcher(identifier); + if (matcher.matches()) { + return matcher.group(1); + } + } + + // Check additional prefixes supported in the config file + String[] additionalPrefixes = configurationService.getArrayProperty("handle.additional.prefixes"); + for (String additionalPrefix : additionalPrefixes) { + if (identifier.startsWith(additionalPrefix + "/")) { + // prefix is the equivalent of 123456789 in 123456789/???; don't strip + return identifier; + } + } + + return null; + } } diff --git a/dspace-api/src/main/java/org/dspace/handle/service/HandleService.java b/dspace-api/src/main/java/org/dspace/handle/service/HandleService.java index 47b469b91c..df20eac01a 100644 --- a/dspace-api/src/main/java/org/dspace/handle/service/HandleService.java +++ b/dspace-api/src/main/java/org/dspace/handle/service/HandleService.java @@ -181,4 +181,15 @@ public interface HandleService { public void modifyHandleDSpaceObject(Context context, String handle, DSpaceObject newOwner) throws SQLException; int countTotal(Context context) throws SQLException; + + /** + * Format a handle ~ + * - hdl:123456789/1 -> 123456789/1 + * - info:hdl/123456789/1 -> 123456789/1 + * - https://hdl.handle.net/123456789/1 -> 123456789/1 + * + * @param identifier + * @return + */ + String formatHandle(String identifier); } diff --git a/dspace-api/src/main/java/org/dspace/identifier/HandleIdentifierProvider.java b/dspace-api/src/main/java/org/dspace/identifier/HandleIdentifierProvider.java index 2aa2ce3baa..6b2afbbbe0 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/HandleIdentifierProvider.java +++ b/dspace-api/src/main/java/org/dspace/identifier/HandleIdentifierProvider.java @@ -60,32 +60,7 @@ public class HandleIdentifierProvider extends IdentifierProvider { @Override public boolean supports(String identifier) { - String prefix = handleService.getPrefix(); - String canonicalPrefix = DSpaceServicesFactory.getInstance().getConfigurationService() - .getProperty("handle.canonical.prefix"); - if (identifier == null) { - return false; - } - // return true if handle has valid starting pattern - if (identifier.startsWith(prefix + "/") - || identifier.startsWith(canonicalPrefix) - || identifier.startsWith("hdl:") - || identifier.startsWith("info:hdl") - || identifier.matches("^https?://hdl\\.handle\\.net/.*") - || identifier.matches("^https?://.+/handle/.*")) { - return true; - } - - //Check additional prefixes supported in the config file - String[] additionalPrefixes = DSpaceServicesFactory.getInstance().getConfigurationService() - .getArrayProperty("handle.additional.prefixes"); - for (String additionalPrefix : additionalPrefixes) { - if (identifier.startsWith(additionalPrefix + "/")) { - return true; - } - } - - return false; + return handleService.formatHandle(identifier) != null; } @Override @@ -161,6 +136,7 @@ public class HandleIdentifierProvider extends IdentifierProvider { public DSpaceObject resolve(Context context, String identifier, String... attributes) { // We can do nothing with this, return null try { + identifier = handleService.formatHandle(identifier); return handleService.resolveToObject(context, identifier); } catch (IllegalStateException | SQLException e) { log.error(LogManager.getHeader(context, "Error while resolving handle to item", "handle: " + identifier), diff --git a/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProvider.java b/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProvider.java index 859c20309a..34411e999c 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProvider.java +++ b/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProvider.java @@ -78,33 +78,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider { @Override public boolean supports(String identifier) { - String prefix = handleService.getPrefix(); - String canonicalPrefix = DSpaceServicesFactory.getInstance().getConfigurationService() - .getProperty("handle.canonical.prefix"); - if (identifier == null) { - return false; - } - // return true if handle has valid starting pattern - if (identifier.startsWith(prefix + "/") - || identifier.startsWith(canonicalPrefix) - || identifier.startsWith("hdl:") - || identifier.startsWith("info:hdl") - || identifier.matches("^https?://hdl\\.handle\\.net/.*") - || identifier.matches("^https?://.+/handle/.*")) { - return true; - } - - //Check additional prefixes supported in the config file - String[] additionalPrefixes = DSpaceServicesFactory.getInstance().getConfigurationService() - .getArrayProperty("handle.additional.prefixes"); - for (String additionalPrefix : additionalPrefixes) { - if (identifier.startsWith(additionalPrefix + "/")) { - return true; - } - } - - // otherwise, assume invalid handle - return false; + return handleService.formatHandle(identifier) != null; } @Override @@ -310,6 +284,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider { public DSpaceObject resolve(Context context, String identifier, String... attributes) { // We can do nothing with this, return null try { + identifier = handleService.formatHandle(identifier); return handleService.resolveToObject(context, identifier); } catch (IllegalStateException | SQLException e) { log.error(LogManager.getHeader(context, "Error while resolving handle to item", "handle: " + identifier), diff --git a/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProviderWithCanonicalHandles.java b/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProviderWithCanonicalHandles.java index 82160bf92c..e68048be9f 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProviderWithCanonicalHandles.java +++ b/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProviderWithCanonicalHandles.java @@ -72,33 +72,7 @@ public class VersionedHandleIdentifierProviderWithCanonicalHandles extends Ident @Override public boolean supports(String identifier) { - String prefix = handleService.getPrefix(); - String canonicalPrefix = DSpaceServicesFactory.getInstance().getConfigurationService() - .getProperty("handle.canonical.prefix"); - if (identifier == null) { - return false; - } - // return true if handle has valid starting pattern - if (identifier.startsWith(prefix + "/") - || identifier.startsWith(canonicalPrefix) - || identifier.startsWith("hdl:") - || identifier.startsWith("info:hdl") - || identifier.matches("^https?://hdl\\.handle\\.net/.*") - || identifier.matches("^https?://.+/handle/.*")) { - return true; - } - - //Check additional prefixes supported in the config file - String[] additionalPrefixes = DSpaceServicesFactory.getInstance().getConfigurationService() - .getArrayProperty("handle.additional.prefixes"); - for (String additionalPrefix : additionalPrefixes) { - if (identifier.startsWith(additionalPrefix + "/")) { - return true; - } - } - - // otherwise, assume invalid handle - return false; + return handleService.formatHandle(identifier) != null; } @Override diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/IdentifierRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/IdentifierRestControllerIT.java index bd67289330..9927d37286 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/IdentifierRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/IdentifierRestControllerIT.java @@ -12,7 +12,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; +import org.dspace.builder.ItemBuilder; +import org.dspace.content.Collection; +import org.dspace.content.Item; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -50,6 +54,32 @@ public class IdentifierRestControllerIT extends AbstractControllerIntegrationTes .andExpect(header().string("Location", communityDetail)); } + @Test + + public void testValidIdentifierItemHandlePrefix() throws Exception { + //We turn off the authorization system in order to create the structure as defined below + context.turnOffAuthorisationSystem(); + + // Create an item with a handle identifier + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection owningCollection = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Owning Collection") + .build(); + Item item = ItemBuilder.createItem(context, owningCollection) + .withTitle("Test item") + .build(); + + String handle = item.getHandle(); + String itemLocation = REST_SERVER_URL + "core/items/" + item.getID(); + + getClient().perform(get("/api/pid/find?id=hdl:{handle}", handle)) + .andExpect(status().isFound()) + // We expect a Location header to redirect to the item's page + .andExpect(header().string("Location", itemLocation)); + } + @Test public void testUnexistentIdentifier() throws Exception { getClient().perform(get("/api/pid/find?id={id}","fakeIdentifier")) From dcaadba772b3e24fe301d7feebe4bcd3755fee06 Mon Sep 17 00:00:00 2001 From: Raf Ponsaerts Date: Tue, 16 Mar 2021 14:53:45 +0100 Subject: [PATCH 138/179] cleanup --- .../indexobject/InprogressSubmissionIndexFactoryImpl.java | 1 + .../indexobject/WorkflowItemIndexFactoryImpl.java | 6 ------ .../indexobject/WorkspaceItemIndexFactoryImpl.java | 8 -------- .../test/java/org/dspace/builder/ClaimedTaskBuilder.java | 4 ---- 4 files changed, 1 insertion(+), 18 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/InprogressSubmissionIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/InprogressSubmissionIndexFactoryImpl.java index 68b26a61da..7f06e7d653 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/InprogressSubmissionIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/InprogressSubmissionIndexFactoryImpl.java @@ -63,6 +63,7 @@ public abstract class InprogressSubmissionIndexFactoryImpl List locations = indexableCollectionService. getCollectionLocations(context, inProgressSubmission.getCollection()); + // Add item metadata indexableItemService.addDiscoveryFields(doc, context, item, SearchUtils.getAllDiscoveryConfigurations(item)); indexableCollectionService.storeCommunityCollectionLocations(doc, locations); } diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkflowItemIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkflowItemIndexFactoryImpl.java index 9e2f7ba30c..0bb114e189 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkflowItemIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkflowItemIndexFactoryImpl.java @@ -19,8 +19,6 @@ import org.apache.solr.common.SolrInputDocument; import org.dspace.content.Item; import org.dspace.core.Context; import org.dspace.discovery.IndexableObject; -import org.dspace.discovery.SearchUtils; -import org.dspace.discovery.configuration.DiscoveryConfiguration; import org.dspace.discovery.indexobject.factory.WorkflowItemIndexFactory; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; @@ -75,10 +73,6 @@ public class WorkflowItemIndexFactoryImpl final SolrInputDocument doc = super.buildDocument(context, indexableObject); final XmlWorkflowItem workflowItem = indexableObject.getIndexedObject(); final Item item = workflowItem.getItem(); - // Add the item metadata as configured -// List discoveryConfigurations = SearchUtils -// .getAllDiscoveryConfigurations(workflowItem); -// indexableItemService.addDiscoveryFields(doc, context, item, discoveryConfigurations); String acvalue = DSpaceServicesFactory.getInstance().getConfigurationService() .getProperty("discovery.facet.namedtype.workflow.item"); diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkspaceItemIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkspaceItemIndexFactoryImpl.java index 2e68a72627..05c82820de 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkspaceItemIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/WorkspaceItemIndexFactoryImpl.java @@ -19,8 +19,6 @@ import org.apache.solr.common.SolrInputDocument; import org.dspace.content.WorkspaceItem; import org.dspace.content.service.WorkspaceItemService; import org.dspace.core.Context; -import org.dspace.discovery.SearchUtils; -import org.dspace.discovery.configuration.DiscoveryConfiguration; import org.dspace.discovery.indexobject.factory.WorkspaceItemIndexFactory; import org.dspace.services.factory.DSpaceServicesFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -71,12 +69,6 @@ public class WorkspaceItemIndexFactoryImpl acvalue = indexableObject.getTypeText(); } addNamedResourceTypeIndex(doc, acvalue); - final WorkspaceItem inProgressSubmission = indexableObject.getIndexedObject(); - - // Add the item metadata as configured -// List discoveryConfigurations = SearchUtils -// .getAllDiscoveryConfigurations(inProgressSubmission); -// indexableItemService.addDiscoveryFields(doc, context, inProgressSubmission.getItem(), discoveryConfigurations); return doc; } diff --git a/dspace-api/src/test/java/org/dspace/builder/ClaimedTaskBuilder.java b/dspace-api/src/test/java/org/dspace/builder/ClaimedTaskBuilder.java index 56d5bb134f..63c03c4a91 100644 --- a/dspace-api/src/test/java/org/dspace/builder/ClaimedTaskBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/ClaimedTaskBuilder.java @@ -16,10 +16,8 @@ import org.dspace.content.Item; import org.dspace.content.LicenseUtils; import org.dspace.content.MetadataSchemaEnum; import org.dspace.content.WorkspaceItem; -import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.event.Event; import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.Workflow; @@ -95,8 +93,6 @@ public class ClaimedTaskBuilder extends AbstractBuilder Date: Tue, 16 Mar 2021 16:09:28 +0100 Subject: [PATCH 139/179] added tests that prove search links in facet values don't contain the configuration --- .../app/rest/DiscoveryRestControllerIT.java | 137 ++++++++++++++++++ .../app/rest/matcher/SearchResultMatcher.java | 12 ++ 2 files changed, 149 insertions(+) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java index 5d97062d36..7123d0f072 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java @@ -4960,4 +4960,141 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest )) .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))); } + + @Test + public void discoverSearchFacetValuesTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community").build(); + + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community").build(); + + Collection col1 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 1").build(); + + Collection col2 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 2").build(); + + ItemBuilder.createItem(context, col1) + .withTitle("Public Test Item") + .withIssueDate("2010-10-17") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry").build(); + + ItemBuilder.createItem(context, col2) + .withTitle("Withdrawn Test Item") + .withIssueDate("1990-02-13") + .withAuthor("Smith, Maria") + .withAuthor("Doe, Jane") + .withSubject("ExtraEntry") + .withdrawn().build(); + + ItemBuilder.createItem(context, col2) + .withTitle("Private Test Item") + .withIssueDate("2010-02-13") + .withAuthor("Smith, Maria") + .withAuthor("Doe, Jane") + .withSubject("AnotherTest") + .withSubject("ExtraEntry") + .makeUnDiscoverable().build(); + + context.restoreAuthSystemState(); + + String adminToken = getAuthToken(admin.getEmail(), password); + + getClient(adminToken).perform(get("/api/discover/facets/discoverable") + .param("configuration", "administrativeView") + .param("sort", "score,DESC") + .param("page", "0") + .param("size", "10")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._links.self.href",containsString( + "/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC"))) + .andExpect(jsonPath("$._embedded.values", Matchers.containsInAnyOrder( + SearchResultMatcher.matchEmbeddedFacetValues("true", 2, "discover", + "/api/discover/search/objects?configuration=administrativeView&f.discoverable=true,equals"), + SearchResultMatcher.matchEmbeddedFacetValues("false", 1, "discover", + "/api/discover/search/objects?configuration=administrativeView&f.discoverable=false,equals") + ))); + + } + + @Test + public void discoverSearchFacetValuesPaginationTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community").build(); + + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community").build(); + + Collection col1 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 1").build(); + + Collection col2 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 2").build(); + + ItemBuilder.createItem(context, col1) + .withTitle("Public Test Item") + .withIssueDate("2010-10-17") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry").build(); + + ItemBuilder.createItem(context, col2) + .withTitle("Withdrawn Test Item") + .withIssueDate("1990-02-13") + .withAuthor("Smith, Maria") + .withAuthor("Doe, Jane") + .withSubject("ExtraEntry") + .withdrawn().build(); + + ItemBuilder.createItem(context, col2) + .withTitle("Private Test Item") + .withIssueDate("2010-02-13") + .withAuthor("Smith, Maria") + .withAuthor("Doe, Jane") + .withSubject("AnotherTest") + .withSubject("ExtraEntry") + .makeUnDiscoverable().build(); + + context.restoreAuthSystemState(); + + String adminToken = getAuthToken(admin.getEmail(), password); + + getClient(adminToken).perform(get("/api/discover/facets/discoverable") + .param("configuration", "administrativeView") + .param("sort", "score,DESC") + .param("page", "0") + .param("size", "1")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._links.self.href",containsString( + "/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC"))) + .andExpect(jsonPath("$._links.next.href",containsString( + "/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC&page=1&size=1"))) + .andExpect(jsonPath("$._embedded.values", Matchers.contains( + SearchResultMatcher.matchEmbeddedFacetValues("true", 2, "discover", + "/api/discover/search/objects?configuration=administrativeView&f.discoverable=true,equals") + ))); + + getClient(adminToken).perform(get("/api/discover/facets/discoverable") + .param("configuration", "administrativeView") + .param("sort", "score,DESC") + .param("page", "1") + .param("size", "1")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._links.first.href",containsString( + "/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC&page=0&size=1"))) + .andExpect(jsonPath("$._links.prev.href",containsString( + "/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC&page=0&size=1"))) + .andExpect(jsonPath("$._links.self.href",containsString( + "/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC&page=1&size=1"))) + .andExpect(jsonPath("$._embedded.values", Matchers.contains( + SearchResultMatcher.matchEmbeddedFacetValues("false", 1, "discover", + "/api/discover/search/objects?configuration=administrativeView&f.discoverable=false,equals") + ))); + } + } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchResultMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchResultMatcher.java index 07a37134de..21215802fb 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchResultMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchResultMatcher.java @@ -83,4 +83,16 @@ public class SearchResultMatcher { )) ); } + + public static Matcher matchEmbeddedFacetValues(String label, int count, + String type, + String search_href) { + return allOf( + hasJsonPath("$.label", is(label)), + hasJsonPath("$.count", is(count)), + hasJsonPath("$.type", is(type)), + hasJsonPath("$._links.search.href", containsString(search_href)) + ); + } + } From 3d37e1cb9b3740e36673fe42d1d12e81c217aa8a Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Tue, 16 Mar 2021 16:14:40 +0100 Subject: [PATCH 140/179] added a fix that able to add configuration in search links of facet values --- .../main/java/org/dspace/app/rest/DiscoveryRestController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java index d167d2a84d..815d7254a7 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java @@ -201,6 +201,8 @@ public class DiscoveryRestController implements InitializingBean { FacetResultsRest facetResultsRest = discoveryRestRepository .getFacetObjects(facetName, prefix, query, dsoTypes, dsoScope, configuration, searchFilters, page); + facetResultsRest.setConfiguration(configuration); + FacetResultsResource facetResultsResource = converter.toResource(facetResultsRest); halLinkService.addLinks(facetResultsResource, page); From 025864a1491127d423ecdb7795a1c1d71517f6eb Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Wed, 17 Mar 2021 10:44:28 +0100 Subject: [PATCH 141/179] added test that proves right functionality of workflow --- .../app/rest/TaskRestRepositoriesIT.java | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java index 0afea26cbd..0f082e2d59 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/TaskRestRepositoriesIT.java @@ -10,6 +10,10 @@ package org.dspace.app.rest; import static com.jayway.jsonpath.JsonPath.read; import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.springframework.data.rest.webmvc.RestMediaTypes.TEXT_URI_LIST_VALUE; +import static org.springframework.http.MediaType.parseMediaType; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.fileUpload; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -47,6 +51,9 @@ import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.Item; import org.dspace.eperson.EPerson; +import org.dspace.eperson.Group; +import org.dspace.eperson.factory.EPersonServiceFactory; +import org.dspace.eperson.service.GroupService; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig; @@ -4133,4 +4140,162 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest { .param("uuid", witem.getItem().getID().toString())) .andExpect(status().isNoContent()); } + + @Test + public void addReviewerToRunningWorkflowTest() throws Exception { + + GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); + + context.turnOffAuthorisationSystem(); + + EPerson reviewer1 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + EPerson reviewer2 = EPersonBuilder.createEPerson(context) + .withEmail("reviewer2@example.com") + .withPassword(password).build(); + + EPerson reviewerOther = EPersonBuilder.createEPerson(context) + .withEmail("reviewerOther@example.com") + .withPassword(password).build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community").build(); + + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community").build(); + + Collection col1 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer1) + .withWorkflowGroup(2, reviewer2) + .build(); + + Group firstWorkflowGroup = col1.getWorkflowStep1(context); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password) + .build(); + + context.setCurrentUser(submitter); + + // create a workflowitem (so a pool task in step1) + XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1) + .withTitle("Test title") + .withIssueDate("2021-02-11") + .withSubject("ExtraEntry").build(); + + Item item = witem.getItem(); + + context.restoreAuthSystemState(); + + String reviewer1Token = getAuthToken(reviewer1.getEmail(), password); + String reviewer2Token = getAuthToken(reviewer2.getEmail(), password); + String reviewerOtherToken = getAuthToken(reviewerOther.getEmail(), password); + + String adminToken = getAuthToken(admin.getEmail(), password); + + AtomicReference idRef = new AtomicReference(); + + Step step = xmlWorkflowFactory.getStepByName("reviewstep"); + + // step 1 + getClient(reviewer1Token).perform(get("/api/workflow/pooltasks/search/findByUser") + .param("uuid", reviewer1.getID().toString()) + .param("projection", "full")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( + Matchers.allOf( + Matchers.is(PoolTaskMatcher.matchPoolTask(null, "reviewstep")), + hasJsonPath("$._embedded.step", WorkflowStepMatcher.matchWorkflowStepEntry(step)), + hasJsonPath("$._embedded.workflowitem", + Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( + witem, "Test title", "2021-02-11", "ExtraEntry"))) + )))) + .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/workflow/pooltasks"))) + .andExpect(jsonPath("$.page.size", is(20))) + .andExpect(jsonPath("$.page.totalElements", is(1))) + .andDo((result -> idRef + .set(read(result.getResponse().getContentAsString(), "$._embedded.pooltasks[0].id")))); + + assertFalse(groupService.isMember(context, reviewerOther, firstWorkflowGroup)); + + getClient(adminToken).perform(post("/api/eperson/groups/" + firstWorkflowGroup.getID() + "/epersons") + .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) + .content(REST_SERVER_URL + "eperson/groups/" + reviewerOther.getID())) + .andExpect(status().isNoContent()); + + assertTrue(groupService.isMember(context, reviewerOther, firstWorkflowGroup)); + + getClient(reviewerOtherToken).perform(get("/api/workflow/pooltasks/search/findByUser") + .param("uuid", reviewerOther.getID().toString()) + .param("projection", "full")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.pooltasks", + Matchers.contains(Matchers.allOf(Matchers.is(PoolTaskMatcher.matchPoolTask(null, "reviewstep")), + hasJsonPath("$._embedded.step", WorkflowStepMatcher.matchWorkflowStepEntry(step)), + hasJsonPath("$._embedded.workflowitem", + Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem, + "Test title", "2021-02-11", "ExtraEntry"))))))) + .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/workflow/pooltasks"))) + .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(1))) + .andDo((result -> idRef + .set(read(result.getResponse().getContentAsString(), "$._embedded.pooltasks[0].id")))); + + // claim the task + getClient(reviewerOtherToken).perform(post("/api/workflow/claimedtasks") + .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) + .content("/api/workflow/pooltasks/" + idRef.get())) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) + .andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id"))); + + getClient(reviewerOtherToken).perform(get("/api/workflow/claimedtasks/search/findByUser") + .param("uuid", reviewerOther.getID().toString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.claimedtasks[0]._embedded.workflowitem", + Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( + witem, "Test title", "2021-02-11", "ExtraEntry")))) + .andExpect(jsonPath("$.page.totalElements", is(1))); + + WorkflowActionConfig workflowAction = xmlWorkflowFactory.getActionByName("reviewaction"); + + // approve the claimedTask, wf step 1 + getClient(reviewerOtherToken).perform(post("/api/workflow/claimedtasks/" + idRef.get()) + .param("submit_approve", "true") + .contentType(MediaType.APPLICATION_FORM_URLENCODED)) + .andExpect(status().isNoContent()); + + step = xmlWorkflowFactory.getStepByName("editstep"); + + // step 2 + getClient(reviewer2Token).perform(get("/api/workflow/pooltasks/search/findByUser") + .param("uuid", reviewer2.getID().toString()).param("projection", "full")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.pooltasks", Matchers.contains( + Matchers.allOf( + Matchers.is(PoolTaskMatcher.matchPoolTask(null, "editstep")), + hasJsonPath("$._embedded.step", WorkflowStepMatcher.matchWorkflowStepEntry(step)), + hasJsonPath("$._embedded.workflowitem", + Matchers.is(WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject( + witem, "Test title", "2021-02-11", "ExtraEntry"))) + )))) + .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/workflow/pooltasks"))) + .andExpect(jsonPath("$.page.size", is(20))) + .andExpect(jsonPath("$.page.totalElements", is(1))) + .andDo((result -> idRef + .set(read(result.getResponse().getContentAsString(), "$._embedded.pooltasks[0].id")))); + + // claim the task + getClient(reviewer2Token).perform(post("/api/workflow/claimedtasks") + .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) + .content("/api/workflow/pooltasks/" + idRef.get())) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.type", is("claimedtask"))))) + .andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id"))); + } + } From 7bacbe73d43fb5527e1c83c724968694d7172a0f Mon Sep 17 00:00:00 2001 From: Raf Ponsaerts Date: Wed, 17 Mar 2021 12:42:47 +0100 Subject: [PATCH 142/179] Fixed authorityKey in facet endpoint response and constructed a test for this --- .../java/org/dspace/builder/ItemBuilder.java | 4 ++ .../app/rest/model/SearchFacetValueRest.java | 1 - .../app/rest/DiscoveryRestControllerIT.java | 54 ++++++++++--------- .../app/rest/matcher/FacetValueMatcher.java | 11 ++++ 4 files changed, 45 insertions(+), 25 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java b/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java index dd033223a4..feaf42bee0 100644 --- a/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java @@ -73,6 +73,10 @@ public class ItemBuilder extends AbstractDSpaceObjectBuilder { public ItemBuilder withAuthor(final String authorName) { return addMetadataValue(item, MetadataSchemaEnum.DC.getName(), "contributor", "author", authorName); } + public ItemBuilder withAuthor(final String authorName, final String authority, final int confidence) { + return addMetadataValue(item, MetadataSchemaEnum.DC.getName(), "contributor", "author", + null, authorName, authority, confidence); + } public ItemBuilder withPersonIdentifierFirstName(final String personIdentifierFirstName) { return addMetadataValue(item, "person", "givenName", null, personIdentifierFirstName); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchFacetValueRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchFacetValueRest.java index 3a04a207fc..3f5be08712 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchFacetValueRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SearchFacetValueRest.java @@ -22,7 +22,6 @@ public class SearchFacetValueRest extends RestAddressableModel { @JsonIgnore private String filterValue; private long count; - @JsonIgnore private String authorityKey; @JsonIgnore private String sortValue; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java index fd3bc1a351..ab67f1b644 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java @@ -50,6 +50,7 @@ import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; +import org.dspace.content.authority.Choices; import org.dspace.content.authority.service.MetadataAuthorityService; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; @@ -188,10 +189,15 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest @Test public void discoverFacetsAuthorWithAuthorityWithSizeParameter() throws Exception { - configurationService.setProperty("choices.plugin.dc.subject", - "SolrSubjectAuthority"); - configurationService.setProperty("authority.controlled.dc.subject", + configurationService.setProperty("choices.plugin.dc.contributor.author", + "SolrAuthorAuthority"); + configurationService.setProperty("authority.controlled.dc.contributor.author", "true"); + configurationService.setProperty("discovery.browse.authority.ignore-prefered.author", true); + configurationService.setProperty("discovery.index.authority.ignore-prefered.dc.contributor.author", true); + configurationService.setProperty("discovery.browse.authority.ignore-variants.author", true); + configurationService.setProperty("discovery.index.authority.ignore-variants.dc.contributor.author", true); + metadataAuthorityService.clearCache(); @@ -213,38 +219,38 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest Item publicItem1 = ItemBuilder.createItem(context, col1) .withTitle("Public item 1") .withIssueDate("2017-10-17") - .withAuthor("Smith, Donald") - .withAuthor("Doe, John") - .withSubject("History of religion", "VR110102", 600) + .withAuthor("Smith, Donald", "test_authority", Choices.CF_ACCEPTED) + .withAuthor("Doe, John", "test_authority_2", Choices.CF_ACCEPTED) + .withSubject("History of religion") .build(); Item publicItem2 = ItemBuilder.createItem(context, col2) .withTitle("Public item 2") .withIssueDate("2016-02-13") - .withAuthor("Smith, Maria") - .withAuthor("Doe, Jane") - .withSubject("Church studies", "VR110103", 600) - .withSubject("History of religion", "VR110102", 600) + .withAuthor("Smith, Maria", "test_authority_3", Choices.CF_ACCEPTED) + .withAuthor("Doe, Jane", "test_authority_4", Choices.CF_ACCEPTED) + .withSubject("Church studies") + .withSubject("History of religion") .build(); Item publicItem3 = ItemBuilder.createItem(context, col2) .withTitle("Public item 2") .withIssueDate("2016-02-13") - .withAuthor("Smith, Maria") - .withAuthor("Doe, Jane") - .withAuthor("test, test") - .withAuthor("test2, test2") - .withAuthor("Maybe, Maybe") - .withSubject("Missionary studies", "VR110104", 600) - .withSubject("Church studies", "VR110103", 600) - .withSubject("History of religion", "VR110102", 600) + .withAuthor("Smith, Maria", "test_authority_3", Choices.CF_ACCEPTED) + .withAuthor("Doe, Jane", "test_authority_4", Choices.CF_ACCEPTED) + .withAuthor("test, test", "test_authority_5", Choices.CF_ACCEPTED) + .withAuthor("test2, test2", "test_authority_6", Choices.CF_ACCEPTED) + .withAuthor("Maybe, Maybe", "test_authority_7", Choices.CF_ACCEPTED) + .withSubject("Missionary studies") + .withSubject("Church studies") + .withSubject("History of religion") .build(); context.restoreAuthSystemState(); //** WHEN ** //An anonymous user browses this endpoint to find the objects in the system and enters a size of 2 - getClient().perform(get("/api/discover/facets/subject") + getClient().perform(get("/api/discover/facets/author") .param("size", "2")) //** THEN ** @@ -253,12 +259,12 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest //The type needs to be 'discover' .andExpect(jsonPath("$.type", is("discover"))) //The name of the facet needs to be seubject, because that's what we called - .andExpect(jsonPath("$.name", is("subject"))) + .andExpect(jsonPath("$.name", is("author"))) //Because we've constructed such a structure so that we have more than 2 (size) subjects, there // needs to be a next link - .andExpect(jsonPath("$._links.next.href", containsString("api/discover/facets/subject?page"))) + .andExpect(jsonPath("$._links.next.href", containsString("api/discover/facets/author?page"))) //There always needs to be a self link - .andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/subject"))) + .andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author"))) //Because there are more subjects than is represented (because of the size param), hasMore has to // be true //The page object needs to be present and just like specified in the matcher @@ -268,8 +274,8 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest // up in different items //These subjects are the most used ones. Only two show up because of the size. .andExpect(jsonPath("$._embedded.values", containsInAnyOrder( - FacetValueMatcher.entrySubject("History of religion", "VR110102", 3), - FacetValueMatcher.entrySubject("Church studies", "VR110103", 2) + FacetValueMatcher.entryAuthorWithAuthority("Doe, Jane", "test_authority_4", 2), + FacetValueMatcher.entryAuthorWithAuthority("Smith, Maria", "test_authority_3", 2) ))); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java index 146bcbfacd..b56b305148 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetValueMatcher.java @@ -28,6 +28,17 @@ public class FacetValueMatcher { ); } + public static Matcher entryAuthorWithAuthority(String label, String authority, int count) { + return allOf( + hasJsonPath("$.authorityKey", is(authority)), + hasJsonPath("$.count", is(count)), + hasJsonPath("$.label", is(label)), + hasJsonPath("$.type", is("discover")), + hasJsonPath("$._links.search.href", containsString("api/discover/search/objects")), + hasJsonPath("$._links.search.href", containsString("f.author=" + authority + ",authority")) + ); + } + public static Matcher entrySubject(String label, int count) { return allOf( hasJsonPath("$.label", is(label)), From b31cd04f527a5716dee91a88588f274897b4b55a Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Thu, 18 Mar 2021 11:02:06 +0100 Subject: [PATCH 143/179] added test that proves a bug where Item not indexed due to authority value not being in a controlled vocabulary --- .../MetadataAuthorityServiceImpl.java | 5 +++ .../service/MetadataAuthorityService.java | 2 + .../builder/AbstractDSpaceObjectBuilder.java | 15 ++++++++ .../java/org/dspace/builder/ItemBuilder.java | 5 +++ .../org/dspace/discovery/DiscoveryIT.java | 37 +++++++++++++++++++ 5 files changed, 64 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/content/authority/MetadataAuthorityServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/authority/MetadataAuthorityServiceImpl.java index 932d0d2c4c..77a983b967 100644 --- a/dspace-api/src/main/java/org/dspace/content/authority/MetadataAuthorityServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/authority/MetadataAuthorityServiceImpl.java @@ -83,6 +83,11 @@ public class MetadataAuthorityServiceImpl implements MetadataAuthorityService { } + @Override + public void reset() { + isAuthorityRequired = null; + } + public void init() { if (isAuthorityRequired == null) { diff --git a/dspace-api/src/main/java/org/dspace/content/authority/service/MetadataAuthorityService.java b/dspace-api/src/main/java/org/dspace/content/authority/service/MetadataAuthorityService.java index 3cf16b35c9..a0e2d25ce6 100644 --- a/dspace-api/src/main/java/org/dspace/content/authority/service/MetadataAuthorityService.java +++ b/dspace-api/src/main/java/org/dspace/content/authority/service/MetadataAuthorityService.java @@ -112,4 +112,6 @@ public interface MetadataAuthorityService { * @return the list of metadata field with authority control */ public List getAuthorityMetadata(); + + public void reset(); } diff --git a/dspace-api/src/test/java/org/dspace/builder/AbstractDSpaceObjectBuilder.java b/dspace-api/src/test/java/org/dspace/builder/AbstractDSpaceObjectBuilder.java index 69cfd0e136..a2a8aa9d42 100644 --- a/dspace-api/src/test/java/org/dspace/builder/AbstractDSpaceObjectBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/AbstractDSpaceObjectBuilder.java @@ -83,6 +83,21 @@ public abstract class AbstractDSpaceObjectBuilder return (B) this; } + protected > B addMetadataValue(final T dso, final String schema, + final String element, + final String qualifier, + final String language, + final String value, + final String authority, + final int confidence) { + try { + getService().addMetadata(context, dso, schema, element, qualifier, language, value, authority, confidence); + } catch (Exception e) { + return handleException(e); + } + return (B) this; + } + protected > B setMetadataSingleValue(final T dso, final String schema, final String element, final String qualifier, diff --git a/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java b/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java index 604043a4c0..5ff366bfb9 100644 --- a/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java @@ -90,6 +90,11 @@ public class ItemBuilder extends AbstractDSpaceObjectBuilder { return addMetadataValue(item, "relationship", "type", null, relationshipType); } + public ItemBuilder withSubject(final String value, final String authority, final int confidence) { + return addMetadataValue(item, MetadataSchemaEnum.DC.getName(), "subject", null, null, + value, authority, confidence); + } + public ItemBuilder withType(final String type) { return addMetadataValue(item, "dc", "type", null, type); } diff --git a/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java b/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java index f49d83498b..680552bb4c 100644 --- a/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java +++ b/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java @@ -27,6 +27,9 @@ import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; +import org.dspace.content.authority.Choices; +import org.dspace.content.authority.factory.ContentAuthorityServiceFactory; +import org.dspace.content.authority.service.MetadataAuthorityService; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.ItemService; import org.dspace.content.service.WorkspaceItemService; @@ -36,6 +39,7 @@ import org.dspace.discovery.indexobject.IndexablePoolTask; import org.dspace.discovery.indexobject.IndexableWorkflowItem; import org.dspace.discovery.indexobject.IndexableWorkspaceItem; import org.dspace.eperson.EPerson; +import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.workflow.WorkflowException; import org.dspace.xmlworkflow.WorkflowConfigurationException; @@ -73,6 +77,10 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase { .getServiceByName(IndexingService.class.getName(), IndexingService.class); + ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); + + MetadataAuthorityService metadataAuthorityService = ContentAuthorityServiceFactory.getInstance() + .getMetadataAuthorityService(); @Test public void solrRecordsAfterDepositOrDeletionOfWorkspaceItemTest() throws Exception { @@ -273,6 +281,35 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase { } + @Test + public void solrRecordFromMessyItemTest() throws Exception { + configurationService.setProperty("authority.controlled.dc.subject", "true"); + metadataAuthorityService.reset(); + try { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community").build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1").build(); + + ItemBuilder.createItem(context, col1) + .withTitle("Public item 1") + .withIssueDate("2021-01-21") + .withAuthor("Smith, Donald") + .withSubject("Test Value", "NOT-EXISTING", Choices.CF_ACCEPTED) + .build(); + + context.restoreAuthSystemState(); + assertSearchQuery(IndexableItem.TYPE, 1); + } finally { + configurationService.setProperty("authority.controlled.dc.subject", "false"); + metadataAuthorityService.reset(); + } + + } + private void assertSearchQuery(String resourceType, int size) throws SearchServiceException { DiscoverQuery discoverQuery = new DiscoverQuery(); discoverQuery.setQuery("*:*"); From 4bf75e5a05e384ff21e3566b8160f048fff123b1 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Thu, 18 Mar 2021 11:08:56 +0100 Subject: [PATCH 144/179] added fix where Item can't indexed due to authority value not being in a controlled vocabulary --- .../dspace/content/authority/DSpaceControlledVocabulary.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java b/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java index 00c74bea9d..adce37865d 100644 --- a/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java +++ b/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java @@ -13,6 +13,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; @@ -315,6 +316,9 @@ public class DSpaceControlledVocabulary extends SelfNamedPlugin implements Hiera private String getNodeLabel(String key, boolean useHierarchy) { try { Node node = getNode(key); + if (Objects.isNull(node)) { + return null; + } if (useHierarchy) { return this.buildString(node); } else { From 22457403b9d1c5df6115536a19a4dd4f1e276f6f Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Thu, 18 Mar 2021 11:56:07 +0100 Subject: [PATCH 145/179] added javaDoc --- .../content/authority/service/MetadataAuthorityService.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/content/authority/service/MetadataAuthorityService.java b/dspace-api/src/main/java/org/dspace/content/authority/service/MetadataAuthorityService.java index a0e2d25ce6..f0ca8ea7c0 100644 --- a/dspace-api/src/main/java/org/dspace/content/authority/service/MetadataAuthorityService.java +++ b/dspace-api/src/main/java/org/dspace/content/authority/service/MetadataAuthorityService.java @@ -113,5 +113,10 @@ public interface MetadataAuthorityService { */ public List getAuthorityMetadata(); + + /** + * This method has been created to have a way of clearing the cache kept inside + * the service + */ public void reset(); } From 17dd108381c5f6121e960aa316f017e756903a7c Mon Sep 17 00:00:00 2001 From: Raf Ponsaerts Date: Thu, 18 Mar 2021 13:48:20 +0100 Subject: [PATCH 146/179] changed test matching to reflect ordering --- .../dspace/app/rest/BrowsesResourceControllerIT.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java index bb40609ff1..41276bd612 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java @@ -291,10 +291,10 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe //Verify that they're sorted alphabetically .andExpect( jsonPath("$._embedded.entries", - containsInAnyOrder( - BrowseEntryResourceMatcher.matchBrowseEntry("Missionary studies", "VR110104", 1), + contains( + BrowseEntryResourceMatcher.matchBrowseEntry("Church studies", "VR110103", 2), BrowseEntryResourceMatcher.matchBrowseEntry("History of religion", "VR110102", 3), - BrowseEntryResourceMatcher.matchBrowseEntry("Church studies", "VR110103", 2) + BrowseEntryResourceMatcher.matchBrowseEntry("Missionary studies", "VR110104", 1) ) ) ); @@ -313,10 +313,10 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe .andExpect(jsonPath("$.page.totalElements", is(3))) //Check the embedded resources and that they're sorted alphabetically //Check that the subject matches as expected - //Verify that they're sorted alphabetically + //Verify that they're sorted alphabetically descending .andExpect( jsonPath("$._embedded.entries", - containsInAnyOrder( + contains( BrowseEntryResourceMatcher.matchBrowseEntry("Missionary studies", "VR110104", 1), BrowseEntryResourceMatcher.matchBrowseEntry("History of religion", "VR110102", 3), BrowseEntryResourceMatcher.matchBrowseEntry("Church studies", "VR110103", 2) From 8e5c28572f7c80115672251c82c5c81a3bd03d1e Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Thu, 18 Mar 2021 16:40:04 +0100 Subject: [PATCH 147/179] added test that proves bug in discovery search with configuration = workflow --- .../app/rest/DiscoveryRestControllerIT.java | 160 ++++++++++++++++++ .../app/rest/matcher/SearchResultMatcher.java | 2 +- 2 files changed, 161 insertions(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java index 5d97062d36..874d063ec8 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java @@ -43,6 +43,7 @@ import org.dspace.builder.CommunityBuilder; import org.dspace.builder.EPersonBuilder; import org.dspace.builder.GroupBuilder; import org.dspace.builder.ItemBuilder; +import org.dspace.builder.PoolTaskBuilder; import org.dspace.builder.WorkflowItemBuilder; import org.dspace.builder.WorkspaceItemBuilder; import org.dspace.content.Bitstream; @@ -4960,4 +4961,163 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest )) .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))); } + + @Test + public void discoverSearchPoolTaskObjectsTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community").build(); + + EPerson reviewer = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + Collection col = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer, admin).build(); + + ItemBuilder.createItem(context, col) + .withTitle("Punnett square") + .withIssueDate("2016-02-13") + .withAuthor("Bandola, Roman") + .withSubject("ExtraEntry").build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + PoolTaskBuilder.createPoolTask(context, col, reviewer) + .withTitle("Metaphysics") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry").build(); + + PoolTaskBuilder.createPoolTask(context, col, reviewer) + .withTitle("Mathematical Theory") + .withIssueDate("2020-01-19") + .withAuthor("Tommaso, Gattari") + .withSubject("ExtraEntry").build(); + + PoolTaskBuilder.createPoolTask(context, col, reviewer) + .withTitle("Test Metaphysics") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String adminToken = getAuthToken(admin.getEmail(), password); + + getClient(adminToken).perform(get("/api/discover/search/objects") + .param("configuration", "workflow") + .param("sort", "dc.date.issued,DESC") + .param("query", "Mathematical Theory")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.query", is("Mathematical Theory"))) + .andExpect(jsonPath("$.configuration", is("workflow"))) + .andExpect(jsonPath("$._embedded.searchResult._embedded.objects", Matchers.contains( + SearchResultMatcher.match("workflow", "pooltask", "pooltasks") + ))) + .andExpect(jsonPath("$._embedded.searchResult._embedded.objects",Matchers.contains( + allOf(hasJsonPath("$._embedded.indexableObject._embedded.workflowitem._embedded.item", + is(SearchResultMatcher.matchEmbeddedObjectOnItemName("item", "Mathematical Theory")))) + ))) + .andExpect(jsonPath("$._embedded.searchResult.page.totalElements", is(1))); + + getClient(adminToken).perform(get("/api/discover/search/objects") + .param("configuration", "workflow") + .param("sort", "dc.date.issued,DESC") + .param("query", "Metaphysics")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.query", is("Metaphysics"))) + .andExpect(jsonPath("$.configuration", is("workflow"))) + .andExpect(jsonPath("$._embedded.searchResult._embedded.objects", Matchers.containsInAnyOrder( + SearchResultMatcher.match("workflow", "pooltask", "pooltasks"), + SearchResultMatcher.match("workflow", "pooltask", "pooltasks") + ))) + .andExpect(jsonPath("$._embedded.searchResult._embedded.objects",Matchers.containsInAnyOrder( + allOf(hasJsonPath("$._embedded.indexableObject._embedded.workflowitem._embedded.item", + is(SearchResultMatcher.matchEmbeddedObjectOnItemName("item", "Metaphysics")))), + allOf(hasJsonPath("$._embedded.indexableObject._embedded.workflowitem._embedded.item", + is(SearchResultMatcher.matchEmbeddedObjectOnItemName("item", "Test Metaphysics")))) + ))) + .andExpect(jsonPath("$._embedded.searchResult.page.totalElements", is(2))); + } + + @Test + public void discoverSearchPoolTaskObjectsEmptyQueryTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community").build(); + + EPerson reviewer = EPersonBuilder.createEPerson(context) + .withEmail("reviewer1@example.com") + .withPassword(password).build(); + + Collection col = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withWorkflowGroup(1, reviewer, admin).build(); + + ItemBuilder.createItem(context, col) + .withTitle("Punnett square") + .withIssueDate("2016-02-13") + .withAuthor("Bandola, Roman") + .withSubject("ExtraEntry").build(); + + // create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword(password).build(); + + context.setCurrentUser(submitter); + + PoolTaskBuilder.createPoolTask(context, col, reviewer) + .withTitle("Metaphysics") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry").build(); + + PoolTaskBuilder.createPoolTask(context, col, reviewer) + .withTitle("Mathematical Theory") + .withIssueDate("2020-01-19") + .withAuthor("Tommaso, Gattari") + .withSubject("ExtraEntry").build(); + + PoolTaskBuilder.createPoolTask(context, col, reviewer) + .withTitle("Test Metaphysics") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry").build(); + + context.restoreAuthSystemState(); + + String adminToken = getAuthToken(admin.getEmail(), password); + + getClient(adminToken).perform(get("/api/discover/search/objects") + .param("configuration", "workflow") + .param("sort", "dc.date.issued,DESC") + .param("query", "")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.configuration", is("workflow"))) + .andExpect(jsonPath("$._embedded.searchResult._embedded.objects", Matchers.containsInAnyOrder( + SearchResultMatcher.match("workflow", "pooltask", "pooltasks"), + SearchResultMatcher.match("workflow", "pooltask", "pooltasks"), + SearchResultMatcher.match("workflow", "pooltask", "pooltasks") + ))) + .andExpect(jsonPath("$._embedded.searchResult._embedded.objects",Matchers.containsInAnyOrder( + allOf(hasJsonPath("$._embedded.indexableObject._embedded.workflowitem._embedded.item", + is(SearchResultMatcher.matchEmbeddedObjectOnItemName("item", "Mathematical Theory")))), + allOf(hasJsonPath("$._embedded.indexableObject._embedded.workflowitem._embedded.item", + is(SearchResultMatcher.matchEmbeddedObjectOnItemName("item", "Metaphysics")))), + allOf(hasJsonPath("$._embedded.indexableObject._embedded.workflowitem._embedded.item", + is(SearchResultMatcher.matchEmbeddedObjectOnItemName("item", "Test Metaphysics")))) + ))) + .andExpect(jsonPath("$._embedded.searchResult.page.totalElements", is(3))); + } + } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchResultMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchResultMatcher.java index 07a37134de..be388490b5 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchResultMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchResultMatcher.java @@ -61,7 +61,7 @@ public class SearchResultMatcher { ); } - private static Matcher matchEmbeddedObjectOnItemName(String type, String itemName) { + public static Matcher matchEmbeddedObjectOnItemName(String type, String itemName) { return allOf( hasJsonPath("$.uuid", notNullValue()), hasJsonPath("$.name", is(itemName)), From 8a6fd61c99a15ef6be43350cdd93ceda7fdd607c Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Thu, 18 Mar 2021 16:47:18 +0100 Subject: [PATCH 148/179] added item metadata in solr documets of pooltask/claimedkask --- .../indexobject/ClaimedTaskIndexFactoryImpl.java | 13 +++++++++++++ .../indexobject/PoolTaskIndexFactoryImpl.java | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/ClaimedTaskIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/ClaimedTaskIndexFactoryImpl.java index 411aa6a0fb..81c9c613c2 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/ClaimedTaskIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/ClaimedTaskIndexFactoryImpl.java @@ -17,10 +17,14 @@ import java.util.Optional; import org.apache.commons.lang3.StringUtils; import org.apache.solr.common.SolrInputDocument; import org.dspace.core.Context; +import org.dspace.discovery.SearchUtils; +import org.dspace.discovery.configuration.DiscoveryConfiguration; import org.dspace.discovery.indexobject.factory.ClaimedTaskIndexFactory; +import org.dspace.discovery.indexobject.factory.ItemIndexFactory; import org.dspace.discovery.indexobject.factory.WorkflowItemIndexFactory; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.springframework.beans.factory.annotation.Autowired; @@ -36,6 +40,9 @@ public class ClaimedTaskIndexFactoryImpl extends IndexFactoryImpl findAll(Context context) throws SQLException { final Iterator claimedTasks = claimedTaskService.findAll(context).iterator(); @@ -77,6 +84,12 @@ public class ClaimedTaskIndexFactoryImpl extends IndexFactoryImpl discoveryConfigurations = SearchUtils + .getAllDiscoveryConfigurations(xmlWorkflowItem); + indexableItemService.addDiscoveryFields(doc, context, xmlWorkflowItem.getItem(), discoveryConfigurations); return doc; } diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/PoolTaskIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/PoolTaskIndexFactoryImpl.java index e7f2f0a14c..971236da12 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/PoolTaskIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/PoolTaskIndexFactoryImpl.java @@ -17,10 +17,14 @@ import java.util.Optional; import org.apache.commons.lang3.StringUtils; import org.apache.solr.common.SolrInputDocument; import org.dspace.core.Context; +import org.dspace.discovery.SearchUtils; +import org.dspace.discovery.configuration.DiscoveryConfiguration; +import org.dspace.discovery.indexobject.factory.ItemIndexFactory; import org.dspace.discovery.indexobject.factory.PoolTaskIndexFactory; import org.dspace.discovery.indexobject.factory.WorkflowItemIndexFactory; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.xmlworkflow.storedcomponents.PoolTask; +import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.springframework.beans.factory.annotation.Autowired; @@ -37,6 +41,9 @@ public class PoolTaskIndexFactoryImpl extends IndexFactoryImpl findAll(Context context) throws SQLException { final Iterator pooledTasks = poolTaskService.findAll(context).iterator(); @@ -82,6 +89,12 @@ public class PoolTaskIndexFactoryImpl extends IndexFactoryImpl discoveryConfigurations = SearchUtils + .getAllDiscoveryConfigurations(xmlWorkflowItem); + indexableItemService.addDiscoveryFields(doc, context, xmlWorkflowItem.getItem(), discoveryConfigurations); return doc; } From bc703129aa7f783928daa7a5f4010658427f2816 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Thu, 18 Mar 2021 18:40:25 +0100 Subject: [PATCH 149/179] Revert "added item metadata in solr documets of pooltask/claimedkask" This reverts commit 8a6fd61c99a15ef6be43350cdd93ceda7fdd607c. --- .../indexobject/ClaimedTaskIndexFactoryImpl.java | 13 ------------- .../indexobject/PoolTaskIndexFactoryImpl.java | 13 ------------- 2 files changed, 26 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/ClaimedTaskIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/ClaimedTaskIndexFactoryImpl.java index 81c9c613c2..411aa6a0fb 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/ClaimedTaskIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/ClaimedTaskIndexFactoryImpl.java @@ -17,14 +17,10 @@ import java.util.Optional; import org.apache.commons.lang3.StringUtils; import org.apache.solr.common.SolrInputDocument; import org.dspace.core.Context; -import org.dspace.discovery.SearchUtils; -import org.dspace.discovery.configuration.DiscoveryConfiguration; import org.dspace.discovery.indexobject.factory.ClaimedTaskIndexFactory; -import org.dspace.discovery.indexobject.factory.ItemIndexFactory; import org.dspace.discovery.indexobject.factory.WorkflowItemIndexFactory; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService; import org.springframework.beans.factory.annotation.Autowired; @@ -40,9 +36,6 @@ public class ClaimedTaskIndexFactoryImpl extends IndexFactoryImpl findAll(Context context) throws SQLException { final Iterator claimedTasks = claimedTaskService.findAll(context).iterator(); @@ -84,12 +77,6 @@ public class ClaimedTaskIndexFactoryImpl extends IndexFactoryImpl discoveryConfigurations = SearchUtils - .getAllDiscoveryConfigurations(xmlWorkflowItem); - indexableItemService.addDiscoveryFields(doc, context, xmlWorkflowItem.getItem(), discoveryConfigurations); return doc; } diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/PoolTaskIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/PoolTaskIndexFactoryImpl.java index 971236da12..e7f2f0a14c 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/PoolTaskIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/PoolTaskIndexFactoryImpl.java @@ -17,14 +17,10 @@ import java.util.Optional; import org.apache.commons.lang3.StringUtils; import org.apache.solr.common.SolrInputDocument; import org.dspace.core.Context; -import org.dspace.discovery.SearchUtils; -import org.dspace.discovery.configuration.DiscoveryConfiguration; -import org.dspace.discovery.indexobject.factory.ItemIndexFactory; import org.dspace.discovery.indexobject.factory.PoolTaskIndexFactory; import org.dspace.discovery.indexobject.factory.WorkflowItemIndexFactory; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.xmlworkflow.storedcomponents.PoolTask; -import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService; import org.springframework.beans.factory.annotation.Autowired; @@ -41,9 +37,6 @@ public class PoolTaskIndexFactoryImpl extends IndexFactoryImpl findAll(Context context) throws SQLException { final Iterator pooledTasks = poolTaskService.findAll(context).iterator(); @@ -89,12 +82,6 @@ public class PoolTaskIndexFactoryImpl extends IndexFactoryImpl discoveryConfigurations = SearchUtils - .getAllDiscoveryConfigurations(xmlWorkflowItem); - indexableItemService.addDiscoveryFields(doc, context, xmlWorkflowItem.getItem(), discoveryConfigurations); return doc; } From e100063abcbf2e737b19580649fb78cbdc96896a Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 2 Mar 2021 11:16:44 -0600 Subject: [PATCH 150/179] Add tests for expected behavior. CSRF token only refreshes on login, logout or when passed as a param. --- .../rest/AuthenticationRestControllerIT.java | 51 +++++++++++++++++-- .../app/rest/EPersonRestRepositoryIT.java | 11 +++- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/AuthenticationRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/AuthenticationRestControllerIT.java index bb8b47244f..a47c0f1f46 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/AuthenticationRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/AuthenticationRestControllerIT.java @@ -309,7 +309,10 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio // Verify logout via GET does NOT work (throws a 405) getClient(token).perform(get("/api/authn/logout")) - .andExpect(status().isMethodNotAllowed()); + .andExpect(status().isMethodNotAllowed()) + // Verify CSRF token has NOT been changed (as neither the cookie nor header are sent back) + .andExpect(cookie().doesNotExist("DSPACE-XSRF-COOKIE")) + .andExpect(header().doesNotExist("DSPACE-XSRF-TOKEN")); // Verify we are still logged in getClient(token).perform(get("/api/authn/status")) @@ -320,7 +323,10 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio // Verify logout via POST works getClient(token).perform(post("/api/authn/logout")) - .andExpect(status().isNoContent()); + .andExpect(status().isNoContent()) + // New/updated CSRF token should be returned (as both a cookie and header) + .andExpect(cookie().exists("DSPACE-XSRF-COOKIE")) + .andExpect(header().exists("DSPACE-XSRF-TOKEN")); // Verify we are now logged out (authenticated=false) getClient(token).perform(get("/api/authn/status")) @@ -368,6 +374,10 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio String newToken = getClient(token).perform(post("/api/authn/login")) .andExpect(status().isOk()) + // An auth token refresh should also refresh the CSRF token + // (which should be returned in both a cookie & header). + .andExpect(cookie().exists("DSPACE-XSRF-COOKIE")) + .andExpect(header().exists("DSPACE-XSRF-TOKEN")) .andReturn().getResponse().getHeader("Authorization"); assertNotEquals(token, newToken); @@ -413,6 +423,23 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio .andExpect(status().isNoContent()); } + @Test + public void testLoginChangesCSRFToken() throws Exception { + // Login via POST, checking the response for a new CSRF Token + String token = getClient().perform(post("/api/authn/login") + .param("user", eperson.getEmail()) + .param("password", password)) + // Verify that the CSRF token has been changed + // (as both cookie and header should be sent back) + .andExpect(cookie().exists("DSPACE-XSRF-COOKIE")) + .andExpect(header().exists("DSPACE-XSRF-TOKEN")) + .andReturn().getResponse().getHeader("Authorization"); + + //Logout + getClient(token).perform(post("/api/authn/logout")) + .andExpect(status().isNoContent()); + } + @Test // This test is verifying that Spring Security's CORS settings are working as we expect public void testCannotReuseTokenFromUntrustedOrigin() throws Exception { @@ -949,11 +976,29 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio getClient(token).perform(post("/api/authn/shortlivedtokens")) .andExpect(jsonPath("$.token", notNullValue())) .andExpect(jsonPath("$.type", is("shortlivedtoken"))) - .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/authn/shortlivedtokens"))); + .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/authn/shortlivedtokens"))) + // Verify generating short-lived token doesn't change our CSRF token + // (so, neither the CSRF cookie nor header are sent back) + .andExpect(cookie().doesNotExist("DSPACE-XSRF-COOKIE")) + .andExpect(header().doesNotExist("DSPACE-XSRF-TOKEN")); assertEquals(salt, eperson.getSessionSalt()); } + @Test + public void testShortLivedTokenWithCSRFSentViaParam() throws Exception { + String token = getAuthToken(eperson.getEmail(), password); + + // Same request as prior method, but this time we are sending the CSRF token as a querystring param. + // NOTE: getClient() method defaults to sending CSRF tokens as Headers, so we are overriding its behavior here + getClient(token).perform(post("/api/authn/shortlivedtokens").with(csrf())) + // BECAUSE we sent the CSRF token on querystring, it should be regenerated & a new token + // is sent back (in cookie and header). + .andExpect(cookie().exists("DSPACE-XSRF-COOKIE")) + .andExpect(header().exists("DSPACE-XSRF-TOKEN")); + } + + @Test public void testShortLivedTokenNotAuthenticated() throws Exception { getClient().perform(post("/api/authn/shortlivedtokens")) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java index 084c08b231..e6774ebb39 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java @@ -29,6 +29,8 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.cookie; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -1127,9 +1129,11 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest { context.turnOffAuthorisationSystem(); + // Create a new EPerson and ensure canLogin is set to "false" initially EPerson ePerson = EPersonBuilder.createEPerson(context) .withNameInMetadata("John", "Doe") .withEmail("Johndoe@example.com") + .withCanLogin(false) .build(); context.restoreAuthSystemState(); @@ -1148,7 +1152,12 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest { .andExpect(status().isOk()) .andExpect(jsonPath("$.canLogIn", Matchers.is(true))) .andExpect(jsonPath("$.email", Matchers.is("johndoe@example.com"))) - .andExpect(jsonPath("$.netid", Matchers.nullValue())); + .andExpect(jsonPath("$.netid", Matchers.nullValue())) + // Verify CSRF token has NOT been changed (as neither the cookie nor header are sent back) + // This is included in this single test as a simple proof that CSRF tokens don't change on + // basic requests. Additional tests regarding CSRF tokens are in AuthenticationRestControllerIT + .andExpect(cookie().doesNotExist("DSPACE-XSRF-COOKIE")) + .andExpect(header().doesNotExist("DSPACE-XSRF-TOKEN")); } From e0b9a488b5f52f8a9d91bd395e616ae95bd90748 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 2 Mar 2021 11:20:11 -0600 Subject: [PATCH 151/179] Modify behavior to match tests. CSRF token only refreshes on login, logout or when sent via param. --- .../DSpaceCsrfAuthenticationStrategy.java | 15 ++++---- ...JWTTokenRestAuthenticationServiceImpl.java | 35 +++++++++++++++++-- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/DSpaceCsrfAuthenticationStrategy.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/DSpaceCsrfAuthenticationStrategy.java index 9d0f06fdad..e8a31b341a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/DSpaceCsrfAuthenticationStrategy.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/DSpaceCsrfAuthenticationStrategy.java @@ -48,8 +48,10 @@ public class DSpaceCsrfAuthenticationStrategy implements SessionAuthenticationSt *

* Therefore, for DSpace, we've customized this method to ensure a new CSRF Token is NOT generated each time a new * Authentication object is created -- doing so causes the CSRF Token to change with every request. Instead, we - * check to see if the client also passed a CSRF token via a header or parameter. If so, this means the client - * has used (or attempted to use) the token & it must then be regenerated. + * check to see if the client also passed a CSRF token via a querystring parameter (i.e. "_csrf"). If so, this means + * the client has sent the token in a less secure manner & it must then be regenerated. + *

+ * NOTE: We also automatically regenerate CSRF token on login/logout via JWTTokenRestAuthenticationServiceImpl. */ @Override public void onAuthentication(Authentication authentication, @@ -62,13 +64,12 @@ public class DSpaceCsrfAuthenticationStrategy implements SessionAuthenticationSt boolean containsToken = token != null; if (containsToken) { - // Check for header or parameter in request - boolean containsHeader = StringUtils.hasLength(request.getHeader(token.getHeaderName())); + // Check for CSRF token sent as param in request boolean containsParameter = StringUtils.hasLength(request.getParameter(token.getParameterName())); - // If token exists & we've also been sent either the header or parameter - // then we need to reset our token (as it's been used) - if (containsHeader || containsParameter) { + // If token exists was sent in a parameter, then we need to reset our token + // (as sending token in a param is insecure) + if (containsParameter) { this.csrfTokenRepository.saveToken(null, request, response); CsrfToken newToken = this.csrfTokenRepository.generateToken(request); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/jwt/JWTTokenRestAuthenticationServiceImpl.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/jwt/JWTTokenRestAuthenticationServiceImpl.java index 54841e984f..863c10b259 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/jwt/JWTTokenRestAuthenticationServiceImpl.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/jwt/JWTTokenRestAuthenticationServiceImpl.java @@ -22,6 +22,7 @@ import org.apache.commons.lang3.StringUtils; import org.dspace.app.rest.model.wrapper.AuthenticationToken; import org.dspace.app.rest.security.DSpaceAuthentication; import org.dspace.app.rest.security.RestAuthenticationService; +import org.dspace.app.rest.security.WebSecurityConfiguration; import org.dspace.app.rest.utils.ContextUtil; import org.dspace.authenticate.AuthenticationMethod; import org.dspace.authenticate.service.AuthenticationService; @@ -34,6 +35,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseCookie; +import org.springframework.security.web.csrf.CsrfToken; +import org.springframework.security.web.csrf.CsrfTokenRepository; import org.springframework.stereotype.Component; /** @@ -64,6 +67,9 @@ public class JWTTokenRestAuthenticationServiceImpl implements RestAuthentication @Autowired private AuthenticationService authenticationService; + @Autowired + private WebSecurityConfiguration webSecurityConfiguration; + @Override public void afterPropertiesSet() throws Exception { @@ -80,10 +86,14 @@ public class JWTTokenRestAuthenticationServiceImpl implements RestAuthentication String token = loginJWTTokenHandler.createTokenForEPerson(context, request, authentication.getPreviousLoginDate(), groups); - - addTokenToResponse(response, token, addCookie); context.commit(); + // Add newly generated auth token to the response + addTokenToResponse(response, token, addCookie); + + // Reset our CSRF token, generating a new one + resetCSRFToken(request, response); + } catch (JOSEException e) { log.error("JOSE Exception", e); } catch (SQLException e) { @@ -149,6 +159,9 @@ public class JWTTokenRestAuthenticationServiceImpl implements RestAuthentication String token = getLoginToken(request); invalidateAuthenticationCookie(response); loginJWTTokenHandler.invalidateToken(token, request, context); + + // Reset our CSRF token, generating a new one + resetCSRFToken(request, response); } @Override @@ -254,4 +267,22 @@ public class JWTTokenRestAuthenticationServiceImpl implements RestAuthentication return authCookie; } + /** + * Force reset the CSRF Token, causing a new one to be generated. + * This method is used internally during login/logout to ensure a new CSRF token is generated anytime authentication + * information changes. + * @param request current request + * @param response current response + */ + private void resetCSRFToken(HttpServletRequest request, HttpServletResponse response) { + // Get access to our enabled CSRF token repository + CsrfTokenRepository csrfTokenRepository = webSecurityConfiguration.getCsrfTokenRepository(); + + // Remove current CSRF token & generate a new one + // We do this as we want the token to change anytime you login or logout + csrfTokenRepository.saveToken(null, request, response); + CsrfToken newToken = csrfTokenRepository.generateToken(request); + csrfTokenRepository.saveToken(newToken, request, response); + } + } From 158d088fec2df5ca909c89a2900845f1ff9319b7 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 2 Mar 2021 11:21:01 -0600 Subject: [PATCH 152/179] Enhance/add JavaDocs to RestAuthenticationService --- .../security/RestAuthenticationService.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/RestAuthenticationService.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/RestAuthenticationService.java index 88b1d26524..23d7b07684 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/RestAuthenticationService.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/RestAuthenticationService.java @@ -26,6 +26,18 @@ import org.springframework.stereotype.Service; @Service public interface RestAuthenticationService { + /** + * This method should be called after a successful authentication occurs. It gathers the authentication data for + * the currently logged in user, adds it into the auth token & saves that token to the response (optionally + * in a cookie). + * @param request current request + * @param response current response + * @param authentication Authentication data generated by the authentication plugin + * @param addCookie boolean, whether to save the generated auth token to a Cookie or not. Default is false. However, + * some authentication methods may require this information be saved to a cookie (even temporarily) + * in order to complete the login process (e.g. Shibboleth requires this) + * @throws IOException + */ void addAuthenticationDataForUser(HttpServletRequest request, HttpServletResponse response, DSpaceAuthentication authentication, boolean addCookie) throws IOException; @@ -37,13 +49,41 @@ public interface RestAuthenticationService { */ AuthenticationToken getShortLivedAuthenticationToken(Context context, HttpServletRequest request); + /** + * Checks the current request for a valid authentication token. If found, extracts that token and obtains the + * currently logged in EPerson. + * @param request current request + * @param context current DSpace Context + * @return EPerson of the logged in user (if auth token found), or null if no auth token is found + */ EPerson getAuthenticatedEPerson(HttpServletRequest request, Context context); + /** + * Checks the current request for a valid authentication token. If found, returns true. If not found, returns false + * @param request current request + * @return true if this request includes a valid authentication token. False otherwise. + */ boolean hasAuthenticationData(HttpServletRequest request); + /** + * Invalidate the current authentication token/data in the request. This is used during logout to ensure any + * existing authentication data/token is destroyed/invalidated and cannot be reused in later requests. + *

+ * In other words, this method invalidates the authentication data created by addAuthenticationDataForUser(). + * This also should include clearing any Cookie created by that method, usually by calling the separate + * invalidateAuthenticationCookie() method in this same class. + * @param request current request + * @param response current response + * @param context current DSpace Context. + * @throws Exception + */ void invalidateAuthenticationData(HttpServletRequest request, HttpServletResponse response, Context context) throws Exception; + /** + * Get access to the current AuthenticationService + * @return current AuthenticationService + */ AuthenticationService getAuthenticationService(); /** @@ -54,6 +94,16 @@ public interface RestAuthenticationService { */ String getWwwAuthenticateHeaderValue(HttpServletRequest request, HttpServletResponse response); + /** + * Invalidate just the authentication Cookie (optionally created by addAuthenticationDataForUser()), while + * keeping the authentication token valid. + *

+ * This method may be used by authentication services which require a Cookie (i.e. addCookie=true in + * addAuthenticationDataForUser()). It's useful for those services to immediately *remove/discard* the Cookie after + * it has been used. This ensures the auth Cookie is temporary in nature, and is destroyed as soon as it is no + * longer needed. + * @param res current response (where Cookie should be destroyed) + */ void invalidateAuthenticationCookie(HttpServletResponse res); } From 404b8281ee47302962b9d1f8f0ba15ecf127d8bc Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 18 Mar 2021 16:01:45 -0500 Subject: [PATCH 153/179] Enhance expectations in test. Document in comments why we send 2 cookies when CSRF token changes. --- .../security/DSpaceCsrfAuthenticationStrategy.java | 5 ++++- .../app/rest/AuthenticationRestControllerIT.java | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/DSpaceCsrfAuthenticationStrategy.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/DSpaceCsrfAuthenticationStrategy.java index e8a31b341a..b08ddab169 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/DSpaceCsrfAuthenticationStrategy.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/DSpaceCsrfAuthenticationStrategy.java @@ -70,8 +70,11 @@ public class DSpaceCsrfAuthenticationStrategy implements SessionAuthenticationSt // If token exists was sent in a parameter, then we need to reset our token // (as sending token in a param is insecure) if (containsParameter) { + // Note: We first set the token to null & then set a new one. This results in 2 cookies sent, + // the first being empty and the second having the new token. + // This behavior is borrowed from Spring Security's CsrfAuthenticationStrategy, see + // https://github.com/spring-projects/spring-security/blob/5.4.x/web/src/main/java/org/springframework/security/web/csrf/CsrfAuthenticationStrategy.java this.csrfTokenRepository.saveToken(null, request, response); - CsrfToken newToken = this.csrfTokenRepository.generateToken(request); this.csrfTokenRepository.saveToken(newToken, request, response); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/AuthenticationRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/AuthenticationRestControllerIT.java index a47c0f1f46..075188aa09 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/AuthenticationRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/AuthenticationRestControllerIT.java @@ -8,9 +8,11 @@ package org.dspace.app.rest; import static java.lang.Thread.sleep; +import static org.dspace.app.rest.utils.RegexUtils.REGEX_UUID; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.matchesPattern; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.startsWith; import static org.junit.Assert.assertEquals; @@ -378,6 +380,14 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio // (which should be returned in both a cookie & header). .andExpect(cookie().exists("DSPACE-XSRF-COOKIE")) .andExpect(header().exists("DSPACE-XSRF-TOKEN")) + // Whenever our token is changed, we send back 2 cookies + // First cookie will always be empty (removing old value) + // Second cookie has the new token (but unfortunately there's no way to get + // a second cookie of the same name using cookie().value()) + // We adopted this behavior from Spring Security's CSRFAuthenticationStrategy + .andExpect(cookie().value("DSPACE-XSRF-COOKIE", "")) + // CSRF Tokens generated by Spring Security are UUIDs + .andExpect(header().string("DSPACE-XSRF-TOKEN", matchesPattern(REGEX_UUID))) .andReturn().getResponse().getHeader("Authorization"); assertNotEquals(token, newToken); From af226189e0ec0fb6078673a9e7694eb7a1e0798e Mon Sep 17 00:00:00 2001 From: Raf Ponsaerts Date: Fri, 19 Mar 2021 10:57:00 +0100 Subject: [PATCH 154/179] changed cleanup from general tests to after specific test --- .../dspace/AbstractIntegrationTestWithDatabase.java | 13 ------------- .../app/rest/BrowsesResourceControllerIT.java | 5 +++++ .../dspace/app/rest/DiscoveryRestControllerIT.java | 6 ++++++ 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java b/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java index cd49b5cca4..2b6a73673a 100644 --- a/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java +++ b/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java @@ -19,7 +19,6 @@ import org.dspace.authority.MockAuthoritySolrServiceImpl; import org.dspace.authorize.AuthorizeException; import org.dspace.builder.AbstractBuilder; import org.dspace.content.Community; -import org.dspace.content.authority.MetadataAuthorityServiceImpl; import org.dspace.core.Context; import org.dspace.core.I18nUtil; import org.dspace.discovery.MockSolrSearchCore; @@ -198,8 +197,6 @@ public class AbstractIntegrationTestWithDatabase extends AbstractDSpaceIntegrati // Reload our ConfigurationService (to reset configs to defaults again) DSpaceServicesFactory.getInstance().getConfigurationService().reloadConfig(); - cleanupCache(serviceManager); - AbstractBuilder.cleanupBuilderCache(); // NOTE: we explicitly do NOT destroy our default eperson & admin as they @@ -209,16 +206,6 @@ public class AbstractIntegrationTestWithDatabase extends AbstractDSpaceIntegrati } } - /** - * Clean up service caches after tests - * @param serviceManager - */ - private void cleanupCache(ServiceManager serviceManager) { - MetadataAuthorityServiceImpl metadataAuthorityService = serviceManager - .getServiceByName(null, MetadataAuthorityServiceImpl.class); - metadataAuthorityService.clearCache(); - } - /** * Utility method to cleanup a created Context object (to save memory). * This can also be used by individual tests to cleanup context objects they create. diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java index 41276bd612..bd9e7d9356 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BrowsesResourceControllerIT.java @@ -34,6 +34,7 @@ import org.dspace.content.Item; import org.dspace.content.authority.service.MetadataAuthorityService; import org.dspace.eperson.Group; import org.dspace.services.ConfigurationService; +import org.dspace.services.factory.DSpaceServicesFactory; import org.hamcrest.Matchers; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -323,6 +324,10 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe ) ) ); + DSpaceServicesFactory.getInstance().getConfigurationService().reloadConfig(); + + metadataAuthorityService.clearCache(); + } @Test diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java index ab67f1b644..c982ca663c 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java @@ -55,6 +55,7 @@ import org.dspace.content.authority.service.MetadataAuthorityService; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; import org.dspace.services.ConfigurationService; +import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.xmlworkflow.storedcomponents.ClaimedTask; import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.hamcrest.Matchers; @@ -277,6 +278,11 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest FacetValueMatcher.entryAuthorWithAuthority("Doe, Jane", "test_authority_4", 2), FacetValueMatcher.entryAuthorWithAuthority("Smith, Maria", "test_authority_3", 2) ))); + + DSpaceServicesFactory.getInstance().getConfigurationService().reloadConfig(); + + metadataAuthorityService.clearCache(); + } @Test From 03c8079be8d743ff34d49649579402e4d4e06571 Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Fri, 19 Mar 2021 15:27:53 +0100 Subject: [PATCH 155/179] 77810 - Log 5xx/4xx REST exceptions --- .../DSpaceApiExceptionControllerAdvice.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java index 987c1223cc..6e48ec5478 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java @@ -11,6 +11,7 @@ import static org.springframework.web.servlet.DispatcherServlet.EXCEPTION_ATTRIB import java.io.IOException; import java.sql.SQLException; +import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -53,6 +54,11 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExcep public class DSpaceApiExceptionControllerAdvice extends ResponseEntityExceptionHandler { private static final Logger log = LogManager.getLogger(DSpaceApiExceptionControllerAdvice.class); + /** + * Set of HTTP error codes to log as ERROR with full stacktrace. + */ + private static final Set LOG_AS_ERROR = Set.of(422); + @Autowired private RestAuthenticationService restAuthenticationService; @@ -180,7 +186,10 @@ public class DSpaceApiExceptionControllerAdvice extends ResponseEntityExceptionH } /** - * Send the error to the response. Some errors may also be logged. + * Send the error to the response. + * 5xx errors will be logged as ERROR with a full stack trace, 4xx errors will be logged as WARN without a + * stacktrace. Specific 4xx errors where an ERROR log with full stacktrace is more appropriate are configured in + * {@link #LOG_AS_ERROR} * @param request current request * @param response current response * @param ex Exception thrown @@ -193,11 +202,13 @@ public class DSpaceApiExceptionControllerAdvice extends ResponseEntityExceptionH //Make sure Spring picks up this exception request.setAttribute(EXCEPTION_ATTRIBUTE, ex); - // For now, just logging server errors. // We don't want to fill logs with bad/invalid REST API requests. - if (statusCode == HttpServletResponse.SC_INTERNAL_SERVER_ERROR) { + if (HttpStatus.valueOf(statusCode).is5xxServerError() || LOG_AS_ERROR.contains(statusCode)) { // Log the full error and status code log.error("{} (status:{})", message, statusCode, ex); + } else if (HttpStatus.valueOf(statusCode).is4xxClientError()) { + // Log the error as a single-line WARN + log.warn("{} (status:{})", message, statusCode); } //Exception properties will be set by org.springframework.boot.web.support.ErrorPageFilter From ede3f110734b946e604f330d97d820da53920437 Mon Sep 17 00:00:00 2001 From: Oliver Goldschmidt Date: Wed, 24 Mar 2021 14:24:48 +0100 Subject: [PATCH 156/179] use generic exception instead of special SQLException --- .../main/java/org/dspace/authenticate/LDAPAuthentication.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java b/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java index 5e80a4c06c..48b3fdd3c8 100644 --- a/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java +++ b/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java @@ -156,7 +156,7 @@ public class LDAPAuthentication } } } - } catch (SQLException ex) { + } catch (Exception ex) { // The user is not an LDAP user, so we don't need to worry about them } return Collections.EMPTY_LIST; From 01ff437b7492af6ea8b241f82ae69f7971d3acfb Mon Sep 17 00:00:00 2001 From: Samuel Date: Wed, 24 Mar 2021 16:35:47 +0100 Subject: [PATCH 157/179] fix #1067 metadatafield with blank qualifier --- .../MetadataFieldRestRepository.java | 4 ++ .../rest/MetadatafieldRestRepositoryIT.java | 37 ++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataFieldRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataFieldRestRepository.java index b0a5f526f0..59e547d449 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataFieldRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/MetadataFieldRestRepository.java @@ -249,6 +249,10 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository Date: Thu, 25 Mar 2021 10:55:54 +0100 Subject: [PATCH 158/179] return to SQLException catch and testing for Nullpointers manually --- .../org/dspace/authenticate/LDAPAuthentication.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java b/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java index 48b3fdd3c8..cdeb329ccf 100644 --- a/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java +++ b/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java @@ -141,6 +141,14 @@ public class LDAPAuthentication // Prevents anonymous users from being added to this group, and the second check // ensures they are LDAP users try { + // without a logged in user, this method should return an empty list + if (context.getCurrentUser() == null) { + return Collections.EMPTY_LIST; + } + // if the logged in user does not have a netid, it's not an LDAP user and this method should return an empty list + if (context.getCurrentUser().getNetid() == null) { + return Collections.EMPTY_LIST; + } if (!context.getCurrentUser().getNetid().equals("")) { String groupName = configurationService.getProperty("authentication-ldap.login.specialgroup"); if ((groupName != null) && (!groupName.trim().equals(""))) { @@ -156,7 +164,7 @@ public class LDAPAuthentication } } } - } catch (Exception ex) { + } catch (SQLException ex) { // The user is not an LDAP user, so we don't need to worry about them } return Collections.EMPTY_LIST; From 68d311ddd0c1b2daa9474e3d446f60e145dc08ed Mon Sep 17 00:00:00 2001 From: Oliver Goldschmidt Date: Thu, 25 Mar 2021 11:22:17 +0100 Subject: [PATCH 159/179] fixes style issue --- .../main/java/org/dspace/authenticate/LDAPAuthentication.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java b/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java index cdeb329ccf..f20d6d8315 100644 --- a/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java +++ b/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java @@ -145,7 +145,8 @@ public class LDAPAuthentication if (context.getCurrentUser() == null) { return Collections.EMPTY_LIST; } - // if the logged in user does not have a netid, it's not an LDAP user and this method should return an empty list + // if the logged in user does not have a netid, it's not an LDAP user + // and this method should return an empty list if (context.getCurrentUser().getNetid() == null) { return Collections.EMPTY_LIST; } From a31383ce6f273d5060b12105fe95ceae1ecaef22 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Thu, 25 Mar 2021 11:47:25 +0100 Subject: [PATCH 160/179] Implement community feedbacks --- .../main/java/org/dspace/app/rest/DiscoveryRestController.java | 2 -- .../app/rest/converter/DiscoverFacetResultsConverter.java | 1 + dspace/config/spring/api/discovery.xml | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java index 815d7254a7..d167d2a84d 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/DiscoveryRestController.java @@ -201,8 +201,6 @@ public class DiscoveryRestController implements InitializingBean { FacetResultsRest facetResultsRest = discoveryRestRepository .getFacetObjects(facetName, prefix, query, dsoTypes, dsoScope, configuration, searchFilters, page); - facetResultsRest.setConfiguration(configuration); - FacetResultsResource facetResultsResource = converter.toResource(facetResultsRest); halLinkService.addLinks(facetResultsResource, page); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetResultsConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetResultsConverter.java index 5feb375801..8d4610b6ba 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetResultsConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/DiscoverFacetResultsConverter.java @@ -41,6 +41,7 @@ public class DiscoverFacetResultsConverter { Projection projection) { FacetResultsRest facetResultsRest = new FacetResultsRest(); facetResultsRest.setProjection(projection); + facetResultsRest.setConfiguration(configuration.getId()); setRequestInformation(context, facetName, prefix, query, dsoTypes, dsoScope, searchFilters, searchResult, configuration, facetResultsRest, page, projection); diff --git a/dspace/config/spring/api/discovery.xml b/dspace/config/spring/api/discovery.xml index 76e5a07239..1be6429bc8 100644 --- a/dspace/config/spring/api/discovery.xml +++ b/dspace/config/spring/api/discovery.xml @@ -404,6 +404,7 @@ + From 2d069b019ac9f94be74bc425fe344bda79079b3c Mon Sep 17 00:00:00 2001 From: Oliver Goldschmidt Date: Thu, 25 Mar 2021 12:36:17 +0100 Subject: [PATCH 161/179] fixes #3207: corrects reading of configuration options --- .../main/java/org/dspace/authenticate/LDAPAuthentication.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java b/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java index 5e80a4c06c..969c08083b 100644 --- a/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java +++ b/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java @@ -681,7 +681,7 @@ public class LDAPAuthentication if (StringUtils.isNotBlank(dn)) { System.out.println("dn:" + dn); int i = 1; - String groupMap = configurationService.getProperty("authentication-ldap", "login.groupmap." + i); + String groupMap = configurationService.getProperty("authentication-ldap.login.groupmap." + i); boolean cmp; @@ -721,7 +721,7 @@ public class LDAPAuthentication } } - groupMap = configurationService.getProperty("authentication-ldap", "login.groupmap." + ++i); + groupMap = configurationService.getProperty("authentication-ldap.login.groupmap." + ++i); } } } From be4479100605d9928435c118a2cfb97cdb3ad436 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Thu, 25 Mar 2021 13:25:59 +0100 Subject: [PATCH 162/179] Implement community feedbacks --- .../test/java/org/dspace/discovery/DiscoveryIT.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java b/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java index 680552bb4c..bf994a3618 100644 --- a/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java +++ b/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java @@ -284,7 +284,7 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase { @Test public void solrRecordFromMessyItemTest() throws Exception { configurationService.setProperty("authority.controlled.dc.subject", "true"); - metadataAuthorityService.reset(); + metadataAuthorityService.clearCache(); try { context.turnOffAuthorisationSystem(); @@ -294,6 +294,12 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase { Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) .withName("Collection 1").build(); + context.restoreAuthSystemState(); + + assertSearchQuery(IndexableItem.TYPE, 0); + + context.turnOffAuthorisationSystem(); + ItemBuilder.createItem(context, col1) .withTitle("Public item 1") .withIssueDate("2021-01-21") @@ -305,7 +311,7 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase { assertSearchQuery(IndexableItem.TYPE, 1); } finally { configurationService.setProperty("authority.controlled.dc.subject", "false"); - metadataAuthorityService.reset(); + metadataAuthorityService.clearCache(); } } From deec143f35e94fa969ac77964feffcffab9435d3 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Thu, 25 Mar 2021 16:51:37 +0100 Subject: [PATCH 163/179] added tests --- .../app/rest/DiscoveryRestControllerIT.java | 111 +++++++++++++++++- 1 file changed, 109 insertions(+), 2 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java index 7123d0f072..aeb5d7caeb 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryRestControllerIT.java @@ -12,6 +12,7 @@ import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.emptyOrNullString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -612,7 +613,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest //The scope has to be the same as the one that we've given in the parameters .andExpect(jsonPath("$.scope", is("testScope"))) //There always needs to be a self link available - .andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author"))) + .andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author?scope=testScope"))) //These are all the authors for the items that were created and thus they have to be present in // the embedded values section .andExpect(jsonPath("$._embedded.values", containsInAnyOrder( @@ -640,7 +641,9 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest //The scope has to be same as the param that we've entered .andExpect(jsonPath("$.scope", is("testScope"))) //There always needs to be a self link available - .andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author"))) + .andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author?scope=testScope"))) + .andExpect(jsonPath("$._links.next.href", + containsString("api/discover/facets/author?scope=testScope&page=1&size=2"))) //These are the values that need to be present as it's ordered by count and these authors are the // most common ones in the items that we've created .andExpect(jsonPath("$._embedded.values", containsInAnyOrder( @@ -5097,4 +5100,108 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest ))); } + @Test + public void discoverFacetsTestWithQueryTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community").build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1").build(); + Collection col2 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 2").build(); + + Item publicItem1 = ItemBuilder.createItem(context, col1) + .withTitle("Public item 1") + .withIssueDate("2019-10-17") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry") + .build(); + + Item publicItem2 = ItemBuilder.createItem(context, col2) + .withTitle("Public item 2") + .withIssueDate("2020-02-13") + .withAuthor("Doe, Jane") + .withSubject("TestingForMore").withSubject("ExtraEntry") + .build(); + + Item publicItem3 = ItemBuilder.createItem(context, col2) + .withTitle("Public item 2") + .withIssueDate("2020-02-13") + .withAuthor("Anton, Senek") + .withSubject("AnotherTest").withSubject("TestingForMore") + .withSubject("ExtraEntry") + .build(); + + context.restoreAuthSystemState(); + + getClient().perform(get("/api/discover/facets/author") + .param("query", "Donald")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.type", is("discover"))) + .andExpect(jsonPath("$.name", is("author"))) + .andExpect(jsonPath("$.facetType", is("text"))) + .andExpect(jsonPath("$.scope", is(emptyOrNullString()))) + .andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author?query=Donald"))) + .andExpect(jsonPath("$._embedded.values[0].label", is("Smith, Donald"))) + .andExpect(jsonPath("$._embedded.values[0].count", is(1))) + .andExpect(jsonPath("$._embedded.values[0]._links.search.href", + containsString("api/discover/search/objects?query=Donald&f.author=Smith, Donald,equals"))) + .andExpect(jsonPath("$._embedded.values").value(Matchers.hasSize(1))); + + } + + @Test + public void discoverFacetsTestWithDsoTypeTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community").build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1").build(); + Collection col2 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 2").build(); + + Item publicItem1 = ItemBuilder.createItem(context, col1) + .withTitle("Public item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry") + .build(); + + Item publicItem2 = ItemBuilder.createItem(context, col2) + .withTitle("Public item 2") + .withIssueDate("2020-02-13") + .withAuthor("Doe, Jane") + .withSubject("ExtraEntry") + .build(); + + Item publicItem3 = ItemBuilder.createItem(context, col2) + .withTitle("Public item 2") + .withIssueDate("2020-02-13") + .withAuthor("Anton, Senek") + .withSubject("TestingForMore") + .withSubject("ExtraEntry") + .build(); + + context.restoreAuthSystemState(); + + getClient().perform(get("/api/discover/facets/dateIssued") + .param("dsoType", "Item")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.type", is("discover"))) + .andExpect(jsonPath("$.name", is("dateIssued"))) + .andExpect(jsonPath("$.facetType", is("date"))) + .andExpect(jsonPath("$.scope", is(emptyOrNullString()))) + .andExpect(jsonPath("$._links.self.href", + containsString("api/discover/facets/dateIssued?dsoType=Item"))) + .andExpect(jsonPath("$._embedded.values[0].label", is("2017 - 2020"))) + .andExpect(jsonPath("$._embedded.values[0].count", is(3))) + .andExpect(jsonPath("$._embedded.values[0]._links.search.href", + containsString("api/discover/search/objects?dsoType=Item&f.dateIssued=[2017 TO 2020],equals"))) + .andExpect(jsonPath("$._embedded.values").value(Matchers.hasSize(1))); + + } } From a43e07f89ab5305413fec979c970529f63cee359 Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Fri, 26 Mar 2021 16:20:11 +0100 Subject: [PATCH 164/179] 77582: Rename formatHandle to parseHandle & add @Override --- .../src/main/java/org/dspace/handle/HandleServiceImpl.java | 3 ++- .../main/java/org/dspace/handle/service/HandleService.java | 2 +- .../java/org/dspace/identifier/HandleIdentifierProvider.java | 4 ++-- .../dspace/identifier/VersionedHandleIdentifierProvider.java | 4 ++-- ...VersionedHandleIdentifierProviderWithCanonicalHandles.java | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/handle/HandleServiceImpl.java b/dspace-api/src/main/java/org/dspace/handle/HandleServiceImpl.java index 0deb1e9d76..645b1fdbc4 100644 --- a/dspace-api/src/main/java/org/dspace/handle/HandleServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/handle/HandleServiceImpl.java @@ -386,7 +386,8 @@ public class HandleServiceImpl implements HandleService { return handleDAO.countRows(context); } - public String formatHandle(String identifier) { + @Override + public String parseHandle(String identifier) { if (identifier == null) { return null; } diff --git a/dspace-api/src/main/java/org/dspace/handle/service/HandleService.java b/dspace-api/src/main/java/org/dspace/handle/service/HandleService.java index df20eac01a..62dec25587 100644 --- a/dspace-api/src/main/java/org/dspace/handle/service/HandleService.java +++ b/dspace-api/src/main/java/org/dspace/handle/service/HandleService.java @@ -191,5 +191,5 @@ public interface HandleService { * @param identifier * @return */ - String formatHandle(String identifier); + String parseHandle(String identifier); } diff --git a/dspace-api/src/main/java/org/dspace/identifier/HandleIdentifierProvider.java b/dspace-api/src/main/java/org/dspace/identifier/HandleIdentifierProvider.java index 6b2afbbbe0..7b55a2dd8c 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/HandleIdentifierProvider.java +++ b/dspace-api/src/main/java/org/dspace/identifier/HandleIdentifierProvider.java @@ -60,7 +60,7 @@ public class HandleIdentifierProvider extends IdentifierProvider { @Override public boolean supports(String identifier) { - return handleService.formatHandle(identifier) != null; + return handleService.parseHandle(identifier) != null; } @Override @@ -136,7 +136,7 @@ public class HandleIdentifierProvider extends IdentifierProvider { public DSpaceObject resolve(Context context, String identifier, String... attributes) { // We can do nothing with this, return null try { - identifier = handleService.formatHandle(identifier); + identifier = handleService.parseHandle(identifier); return handleService.resolveToObject(context, identifier); } catch (IllegalStateException | SQLException e) { log.error(LogManager.getHeader(context, "Error while resolving handle to item", "handle: " + identifier), diff --git a/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProvider.java b/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProvider.java index 34411e999c..193f747895 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProvider.java +++ b/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProvider.java @@ -78,7 +78,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider { @Override public boolean supports(String identifier) { - return handleService.formatHandle(identifier) != null; + return handleService.parseHandle(identifier) != null; } @Override @@ -284,7 +284,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider { public DSpaceObject resolve(Context context, String identifier, String... attributes) { // We can do nothing with this, return null try { - identifier = handleService.formatHandle(identifier); + identifier = handleService.parseHandle(identifier); return handleService.resolveToObject(context, identifier); } catch (IllegalStateException | SQLException e) { log.error(LogManager.getHeader(context, "Error while resolving handle to item", "handle: " + identifier), diff --git a/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProviderWithCanonicalHandles.java b/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProviderWithCanonicalHandles.java index e68048be9f..e15abc43b4 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProviderWithCanonicalHandles.java +++ b/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProviderWithCanonicalHandles.java @@ -72,7 +72,7 @@ public class VersionedHandleIdentifierProviderWithCanonicalHandles extends Ident @Override public boolean supports(String identifier) { - return handleService.formatHandle(identifier) != null; + return handleService.parseHandle(identifier) != null; } @Override From 174225923a8a62f8649f7a50b6660a0495b8d91c Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Fri, 26 Mar 2021 16:20:34 +0100 Subject: [PATCH 165/179] 77582: Add unit tests for HandleServiceImpl#parseHandle --- .../org/dspace/handle/HandleServiceTest.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 dspace-api/src/test/java/org/dspace/handle/HandleServiceTest.java diff --git a/dspace-api/src/test/java/org/dspace/handle/HandleServiceTest.java b/dspace-api/src/test/java/org/dspace/handle/HandleServiceTest.java new file mode 100644 index 0000000000..d82cbe61e2 --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/handle/HandleServiceTest.java @@ -0,0 +1,66 @@ +package org.dspace.handle; + +import static org.junit.Assert.*; + +import org.dspace.AbstractUnitTest; +import org.dspace.handle.factory.HandleServiceFactory; +import org.dspace.handle.service.HandleService; +import org.dspace.services.ConfigurationService; +import org.dspace.utils.DSpace; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class HandleServiceTest extends AbstractUnitTest { + protected HandleService handleService = HandleServiceFactory.getInstance().getHandleService(); + protected ConfigurationService configurationService = new DSpace().getConfigurationService(); + + @Before + @Override + public void init() { + super.init(); + + configurationService.setProperty("handle.prefix", "123456789"); + configurationService.setProperty("handle.canonical.prefix", "https://fake.canonical.prefix"); + configurationService.setProperty("handle.additional.prefixes", "987654321, 654321987"); + } + + @Test + public void testParseHandleInvalid() { + assertNull(handleService.parseHandle(null)); + assertNull(handleService.parseHandle("123456789")); + assertNull(handleService.parseHandle("/123456789")); + assertNull(handleService.parseHandle("https://duraspace.org/dspace/")); + assertNull(handleService.parseHandle("10.70131/test_doi_5d2be995d35b6")); + assertNull(handleService.parseHandle("not a handle")); + } + + @Test + public void testParseHandleByPrefix() { + // note: handle pattern after prefix is not checked + assertEquals("123456789/111", handleService.parseHandle("123456789/111")); + } + + @Test + public void testParseHandleByCanonicalPrefix() { + // note: handle pattern after prefix is not checked + assertEquals("111222333/111", handleService.parseHandle("https://fake.canonical.prefix/111222333/111")); + } + + @Test + public void testParseHandleByAdditionalPrefix() { + // note: handle pattern after prefix is not checked + assertEquals("987654321/111", handleService.parseHandle("987654321/111")); + assertEquals("654321987/111", handleService.parseHandle("654321987/111")); + } + + @Test + public void testParseHandleByPattern() { + assertEquals("111222333/111", handleService.parseHandle("hdl:111222333/111")); + assertEquals("111222333/111", handleService.parseHandle("info:hdl/111222333/111")); + assertEquals("111222333/111", handleService.parseHandle("https://hdl.handle.net/111222333/111")); + assertEquals("111222333/111", handleService.parseHandle("http://hdl.handle.net/111222333/111")); + assertEquals("111222333/111", handleService.parseHandle("https://whatever/handle/111222333/111")); + assertEquals("111222333/111", handleService.parseHandle("http://whatever/handle/111222333/111")); + } +} From 9afe043fb7c99a214af06dcb808fb98f4387a517 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 26 Mar 2021 15:19:04 -0500 Subject: [PATCH 166/179] Pin to Postgres 11 in Dockerfiles --- dspace/src/main/docker/dspace-postgres-pgcrypto-curl/Dockerfile | 2 +- dspace/src/main/docker/dspace-postgres-pgcrypto/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace/src/main/docker/dspace-postgres-pgcrypto-curl/Dockerfile b/dspace/src/main/docker/dspace-postgres-pgcrypto-curl/Dockerfile index 8e90ded0df..0e85dd33ce 100644 --- a/dspace/src/main/docker/dspace-postgres-pgcrypto-curl/Dockerfile +++ b/dspace/src/main/docker/dspace-postgres-pgcrypto-curl/Dockerfile @@ -7,7 +7,7 @@ # # This will be deployed as dspace/dspace-postgres-pgcrpyto:loadsql -FROM postgres +FROM postgres:11 ENV POSTGRES_DB dspace ENV POSTGRES_USER dspace diff --git a/dspace/src/main/docker/dspace-postgres-pgcrypto/Dockerfile b/dspace/src/main/docker/dspace-postgres-pgcrypto/Dockerfile index 2368818926..84b7569a2b 100644 --- a/dspace/src/main/docker/dspace-postgres-pgcrypto/Dockerfile +++ b/dspace/src/main/docker/dspace-postgres-pgcrypto/Dockerfile @@ -7,7 +7,7 @@ # # This will be deployed as dspace/dspace-postgres-pgcrpyto:latest -FROM postgres +FROM postgres:11 ENV POSTGRES_DB dspace ENV POSTGRES_USER dspace From 01d47fb639670a239af44bce68e9a80894b115c4 Mon Sep 17 00:00:00 2001 From: yura bondarenko Date: Sat, 27 Mar 2021 18:08:41 +0100 Subject: [PATCH 167/179] Add license header --- .../src/test/java/org/dspace/handle/HandleServiceTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dspace-api/src/test/java/org/dspace/handle/HandleServiceTest.java b/dspace-api/src/test/java/org/dspace/handle/HandleServiceTest.java index d82cbe61e2..b308e2f1d8 100644 --- a/dspace-api/src/test/java/org/dspace/handle/HandleServiceTest.java +++ b/dspace-api/src/test/java/org/dspace/handle/HandleServiceTest.java @@ -1,3 +1,10 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ package org.dspace.handle; import static org.junit.Assert.*; From ec90374ff6ef47b358c0c279e1542ad95258bf44 Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Mon, 29 Mar 2021 09:02:13 +0200 Subject: [PATCH 168/179] 77582: Fix imports --- .../src/test/java/org/dspace/handle/HandleServiceTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/handle/HandleServiceTest.java b/dspace-api/src/test/java/org/dspace/handle/HandleServiceTest.java index b308e2f1d8..5232d5864d 100644 --- a/dspace-api/src/test/java/org/dspace/handle/HandleServiceTest.java +++ b/dspace-api/src/test/java/org/dspace/handle/HandleServiceTest.java @@ -7,7 +7,8 @@ */ package org.dspace.handle; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import org.dspace.AbstractUnitTest; import org.dspace.handle.factory.HandleServiceFactory; @@ -15,7 +16,6 @@ import org.dspace.handle.service.HandleService; import org.dspace.services.ConfigurationService; import org.dspace.utils.DSpace; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; public class HandleServiceTest extends AbstractUnitTest { From c53c1f6909e998dfc186b7fc1cbd60ab6dd74387 Mon Sep 17 00:00:00 2001 From: Samuel Date: Tue, 30 Mar 2021 09:57:00 +0200 Subject: [PATCH 169/179] taskid 78006 Test metadata field caching branch - PR 3160 --- .../service/MetadataFieldServiceTest.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 dspace-api/src/test/java/org/dspace/content/service/MetadataFieldServiceTest.java diff --git a/dspace-api/src/test/java/org/dspace/content/service/MetadataFieldServiceTest.java b/dspace-api/src/test/java/org/dspace/content/service/MetadataFieldServiceTest.java new file mode 100644 index 0000000000..35000c7b62 --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/content/service/MetadataFieldServiceTest.java @@ -0,0 +1,76 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.content.service; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.dspace.AbstractUnitTest; +import org.dspace.content.MetadataField; +import org.dspace.content.MetadataSchema; +import org.dspace.content.factory.ContentServiceFactory; +import org.dspace.core.Context; +import org.junit.Test; + +public class MetadataFieldServiceTest extends AbstractUnitTest { + + private MetadataFieldService metadataFieldService = + ContentServiceFactory.getInstance().getMetadataFieldService(); + private MetadataSchemaService metadataSchemaService = + ContentServiceFactory.getInstance().getMetadataSchemaService(); + + @Test + public void testMetadataFieldCaching() throws Exception { + + MetadataField subjectField = metadataFieldService.findByElement(context, "dc", "subject", null); + MetadataField issnField = metadataFieldService.findByElement(context, "dc", "identifier", "issn"); + + MetadataSchema dspaceSchema = metadataSchemaService.find(context, "dspace"); + + subjectField.setMetadataSchema(dspaceSchema); + issnField.setMetadataSchema(dspaceSchema); + + // Searching for dspace.subject and dspace.identifier.issn should return the already stored metadatafields + assertEquals( + subjectField, + metadataFieldService.findByElement(context, "dspace", "subject", null) + ); + assertEquals( + issnField, + metadataFieldService.findByElement(context, "dspace", "identifier", "issn") + ); + + // Metadatafields dc.subject and dc.identifier.issn should no longer be found + assertNull( + metadataFieldService.findByElement(context, "dc", "subject", null) + ); + assertNull( + metadataFieldService.findByElement(context, "dc", "identifier", "issn") + ); + + // Same tests, new context + + context.complete(); + context = new Context(); + + assertEquals( + subjectField, + metadataFieldService.findByElement(context, "dspace", "subject", null) + ); + assertEquals( + issnField, + metadataFieldService.findByElement(context, "dspace", "identifier", "issn") + ); + assertNull( + metadataFieldService.findByElement(context, "dc", "subject", null) + ); + assertNull( + metadataFieldService.findByElement(context, "dc", "identifier", "issn") + ); + } +} From 535f90e14787400a080c2a89590541959c582dca Mon Sep 17 00:00:00 2001 From: Samuel Date: Tue, 30 Mar 2021 10:42:16 +0200 Subject: [PATCH 170/179] taskid 78099 ItemMetadata caching test --- .../RelationshipMetadataServiceIT.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java b/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java index 41a7e3c85d..5483e79cab 100644 --- a/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java +++ b/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java @@ -9,6 +9,7 @@ package org.dspace.content; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -301,15 +302,21 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author")); assertNull(authorList.get(0).getAuthority()); + //verify there's relation.isPublicationOfAuthor actual metadata + assertEquals(1, rightItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isPublicationOfAuthor")) + .collect(Collectors.toList()).size()); + assertEquals(1, itemService + .getMetadata(rightItem, MetadataSchemaEnum.RELATION.getName(), "isPublicationOfAuthor", null, Item.ANY) + .size()); + //verify there's relation.isAuthorOfPublication actual metadata - plainRelationshipMetadataList = leftItem.getMetadata().stream() + assertEquals(1, leftItem.getMetadata().stream() .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication")) - .collect(Collectors.toList()); - assertThat(plainRelationshipMetadataList.size(), equalTo(1)); - //verify there's relation.isAuthorOfPublication actual metadata - List relationshipMetadataList = itemService - .getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY); - assertThat(relationshipMetadataList.size(), equalTo(1)); + .collect(Collectors.toList()).size()); + assertEquals(1, itemService + .getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY) + .size()); } @Test From 5d9ad392dfad98a4a2405b6853b301542ecf5ebe Mon Sep 17 00:00:00 2001 From: Samuel Date: Tue, 30 Mar 2021 15:01:46 +0200 Subject: [PATCH 171/179] taskid 78006 Test metadata field caching branch - PR 3160 - feedback --- .../service/MetadataFieldServiceTest.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/dspace-api/src/test/java/org/dspace/content/service/MetadataFieldServiceTest.java b/dspace-api/src/test/java/org/dspace/content/service/MetadataFieldServiceTest.java index 35000c7b62..444bee9749 100644 --- a/dspace-api/src/test/java/org/dspace/content/service/MetadataFieldServiceTest.java +++ b/dspace-api/src/test/java/org/dspace/content/service/MetadataFieldServiceTest.java @@ -45,6 +45,22 @@ public class MetadataFieldServiceTest extends AbstractUnitTest { metadataFieldService.findByElement(context, "dspace", "identifier", "issn") ); + // The dspace.subject and dspace.identifier.issn metadatafields should now reference the 'dspace' metadataschema + assertEquals( + "dspace", + metadataFieldService + .findByElement(context, "dspace", "subject", null) + .getMetadataSchema() + .getName() + ); + assertEquals( + "dspace", + metadataFieldService + .findByElement(context, "dspace", "identifier", "issn") + .getMetadataSchema() + .getName() + ); + // Metadatafields dc.subject and dc.identifier.issn should no longer be found assertNull( metadataFieldService.findByElement(context, "dc", "subject", null) @@ -66,6 +82,20 @@ public class MetadataFieldServiceTest extends AbstractUnitTest { issnField, metadataFieldService.findByElement(context, "dspace", "identifier", "issn") ); + assertEquals( + "dspace", + metadataFieldService + .findByElement(context, "dspace", "subject", null) + .getMetadataSchema() + .getName() + ); + assertEquals( + "dspace", + metadataFieldService + .findByElement(context, "dspace", "identifier", "issn") + .getMetadataSchema() + .getName() + ); assertNull( metadataFieldService.findByElement(context, "dc", "subject", null) ); From 1b3ace654b6fa2595fa26996b1776ac1f8427c3a Mon Sep 17 00:00:00 2001 From: Samuel Date: Wed, 31 Mar 2021 12:38:46 +0200 Subject: [PATCH 172/179] taskid 78099 ItemMetadata caching test - feedback --- .../RelationshipMetadataServiceIT.java | 37 +++++++++++++++---- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java b/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java index 5483e79cab..1a4366a5db 100644 --- a/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java +++ b/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java @@ -259,6 +259,14 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa List relationshipMetadataList = itemService .getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY); assertThat(relationshipMetadataList.size(), equalTo(0)); + + //verify there's relation.isPublicationOfAuthor actual metadata on the author + assertThat(rightItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isPublicationOfAuthor")) + .collect(Collectors.toList()).size(), equalTo(1)); + assertThat(itemService + .getMetadata(rightItem, MetadataSchemaEnum.RELATION.getName(), "isPublicationOfAuthor", null, Item.ANY) + .size(), equalTo(1)); } @Test @@ -507,6 +515,14 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa List relationshipMetadataList = itemService .getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY); assertThat(relationshipMetadataList.size(), equalTo(0)); + + //verify there's relation.isPublicationOfAuthor actual metadata on the author + assertThat(rightItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isPublicationOfAuthor")) + .collect(Collectors.toList()).size(), equalTo(1)); + assertThat(itemService + .getMetadata(rightItem, MetadataSchemaEnum.RELATION.getName(), "isPublicationOfAuthor", null, Item.ANY) + .size(), equalTo(1)); } @Test @@ -550,15 +566,20 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author")); assertNull(authorList.get(0).getAuthority()); - //verify there's relation.isAuthorOfPublication actual metadata - plainRelationshipMetadataList = leftItem.getMetadata().stream() + //verify there's relation.isAuthorOfPublication actual metadata on the publication + assertThat(leftItem.getMetadata().stream() .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication")) - .collect(Collectors.toList()); - assertThat(plainRelationshipMetadataList.size(), equalTo(1)); - //verify there's relation.isAuthorOfPublication actual metadata - List relationshipMetadataList = itemService - .getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY); - assertThat(relationshipMetadataList.size(), equalTo(1)); + .collect(Collectors.toList()).size(), equalTo(1)); + assertThat(itemService + .getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY) + .size(), equalTo(1)); + //verify there's relation.isPublicationOfAuthor actual metadata on the author + assertThat(rightItem.getMetadata().stream() + .filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isPublicationOfAuthor")) + .collect(Collectors.toList()).size(), equalTo(1)); + assertThat(itemService + .getMetadata(rightItem, MetadataSchemaEnum.RELATION.getName(), "isPublicationOfAuthor", null, Item.ANY) + .size(), equalTo(1)); } @Test From b85b15f876f91c5fe023e571ed32362e5734e7b6 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 31 Mar 2021 12:18:56 -0500 Subject: [PATCH 173/179] Fix test to determine number of schema in DB prior to checking pagination --- .../rest/MetadataSchemaRestRepositoryIT.java | 62 +++++++++++-------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java index 76238d02c0..f1a1a095b1 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataSchemaRestRepositoryIT.java @@ -29,6 +29,7 @@ import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.builder.MetadataSchemaBuilder; import org.dspace.content.MetadataSchema; +import org.dspace.content.factory.ContentServiceFactory; import org.hamcrest.Matchers; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -271,74 +272,85 @@ public class MetadataSchemaRestRepositoryIT extends AbstractControllerIntegratio @Test public void findAllPaginationTest() throws Exception { + // Determine number of schemas from database + int numberOfSchema = ContentServiceFactory.getInstance() + .getMetadataSchemaService().findAll(context).size(); + // If we return 6 schema per page, determine number of pages we expect + int pageSize = 6; + int numberOfPages = (int) Math.ceil((double) numberOfSchema / pageSize); + + // In these tests we just validate the first 3 pages, as we currently have at least that many schema getClient().perform(get("/api/core/metadataschemas") - .param("size", "6") + .param("size", String.valueOf(pageSize)) .param("page", "0")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) .andExpect(jsonPath("$._embedded.metadataschemas", Matchers.hasItem(matchEntry()))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/core/metadataschemas?"), - Matchers.containsString("page=0"), Matchers.containsString("size=6")))) + Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.self.href", Matchers.allOf( Matchers.containsString("/api/core/metadataschemas?"), - Matchers.containsString("page=0"), Matchers.containsString("size=6")))) + Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.next.href", Matchers.allOf( Matchers.containsString("/api/core/metadataschemas?"), - Matchers.containsString("page=1"), Matchers.containsString("size=6")))) + Matchers.containsString("page=1"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.last.href", Matchers.allOf( Matchers.containsString("/api/core/metadataschemas?"), - Matchers.containsString("page=2"), Matchers.containsString("size=6")))) - .andExpect(jsonPath("$.page.totalElements", is(16))) - .andExpect(jsonPath("$.page.totalPages", is(3))) - .andExpect(jsonPath("$.page.size", is(6))); + Matchers.containsString("page=" + (numberOfPages - 1)), + Matchers.containsString("size=" + pageSize)))) + .andExpect(jsonPath("$.page.totalElements", is(numberOfSchema))) + .andExpect(jsonPath("$.page.totalPages", is(numberOfPages))) + .andExpect(jsonPath("$.page.size", is(pageSize))); getClient().perform(get("/api/core/metadataschemas") - .param("size", "6") + .param("size", String.valueOf(pageSize)) .param("page", "1")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) .andExpect(jsonPath("$._embedded.metadataschemas", Matchers.hasItem(matchEntry()))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/core/metadataschemas?"), - Matchers.containsString("page=0"), Matchers.containsString("size=6")))) + Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( Matchers.containsString("/api/core/metadataschemas?"), - Matchers.containsString("page=0"), Matchers.containsString("size=6")))) + Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.self.href", Matchers.allOf( Matchers.containsString("/api/core/metadataschemas?"), - Matchers.containsString("page=1"), Matchers.containsString("size=6")))) + Matchers.containsString("page=1"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.next.href", Matchers.allOf( Matchers.containsString("/api/core/metadataschemas?"), - Matchers.containsString("page=2"), Matchers.containsString("size=6")))) + Matchers.containsString("page=2"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.last.href", Matchers.allOf( Matchers.containsString("/api/core/metadataschemas?"), - Matchers.containsString("page=2"), Matchers.containsString("size=6")))) - .andExpect(jsonPath("$.page.totalElements", is(16))) - .andExpect(jsonPath("$.page.totalPages", is(3))) - .andExpect(jsonPath("$.page.size", is(6))); + Matchers.containsString("page=" + (numberOfPages - 1)), + Matchers.containsString("size=" + pageSize)))) + .andExpect(jsonPath("$.page.totalElements", is(numberOfSchema))) + .andExpect(jsonPath("$.page.totalPages", is(numberOfPages))) + .andExpect(jsonPath("$.page.size", is(pageSize))); getClient().perform(get("/api/core/metadataschemas") - .param("size", "6") + .param("size", String.valueOf(pageSize)) .param("page", "2")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) .andExpect(jsonPath("$._embedded.metadataschemas", Matchers.hasItem(matchEntry()))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/core/metadataschemas?"), - Matchers.containsString("page=0"), Matchers.containsString("size=6")))) + Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( Matchers.containsString("/api/core/metadataschemas?"), - Matchers.containsString("page=1"), Matchers.containsString("size=6")))) + Matchers.containsString("page=1"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.self.href", Matchers.allOf( Matchers.containsString("/api/core/metadataschemas?"), - Matchers.containsString("page=2"), Matchers.containsString("size=6")))) + Matchers.containsString("page=2"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.last.href", Matchers.allOf( Matchers.containsString("/api/core/metadataschemas?"), - Matchers.containsString("page=2"), Matchers.containsString("size=6")))) - .andExpect(jsonPath("$.page.totalElements", is(16))) - .andExpect(jsonPath("$.page.totalPages", is(3))) - .andExpect(jsonPath("$.page.size", is(6))); + Matchers.containsString("page=" + (numberOfPages - 1)), + Matchers.containsString("size=" + pageSize)))) + .andExpect(jsonPath("$.page.totalElements", is(numberOfSchema))) + .andExpect(jsonPath("$.page.totalPages", is(numberOfPages))) + .andExpect(jsonPath("$.page.size", is(pageSize))); } From 7b4f0c7f448f25b64a2674dce283ac5baf4db4a5 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 31 Mar 2021 13:09:30 -0500 Subject: [PATCH 174/179] Determine metadata field count & pagination dynamically as well --- .../rest/MetadatafieldRestRepositoryIT.java | 75 ++++++++++++------- 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadatafieldRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadatafieldRestRepositoryIT.java index 17c94acc4e..32cb28f09c 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadatafieldRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadatafieldRestRepositoryIT.java @@ -32,6 +32,7 @@ import org.dspace.builder.MetadataSchemaBuilder; import org.dspace.content.MetadataField; import org.dspace.content.MetadataFieldServiceImpl; import org.dspace.content.MetadataSchema; +import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.MetadataSchemaService; import org.hamcrest.Matchers; import org.junit.Before; @@ -966,11 +967,21 @@ public class MetadatafieldRestRepositoryIT extends AbstractControllerIntegration @Test public void findAllPaginationTest() throws Exception { + + // Determine number of metadata fields from database + int numberOfMdFields = ContentServiceFactory.getInstance().getMetadataFieldService().findAll(context).size(); + + // If we return 3 fields per page, determine number of pages we expect + int pageSize = 3; + int numberOfPages = (int) Math.ceil((double) numberOfMdFields / pageSize); + + // Check first page getClient().perform(get("/api/core/metadatafields") - .param("size", "3") + .param("size", String.valueOf(pageSize)) .param("page", "0")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) + // Metadata fields are returned alphabetically. So, look for the first 3 alphabetically .andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItems( MetadataFieldMatcher.matchMetadataFieldByKeys("creativework","datePublished", null), MetadataFieldMatcher.matchMetadataFieldByKeys("creativework", "editor", null), @@ -978,25 +989,28 @@ public class MetadatafieldRestRepositoryIT extends AbstractControllerIntegration ))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/core/metadatafields?"), - Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.self.href", Matchers.allOf( Matchers.containsString("/api/core/metadatafields?"), - Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.next.href", Matchers.allOf( Matchers.containsString("/api/core/metadatafields?"), - Matchers.containsString("page=1"), Matchers.containsString("size=3")))) + Matchers.containsString("page=1"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.last.href", Matchers.allOf( Matchers.containsString("/api/core/metadatafields?"), - Matchers.containsString("page=63"), Matchers.containsString("size=3")))) - .andExpect(jsonPath("$.page.totalElements", is(192))) - .andExpect(jsonPath("$.page.totalPages", is(64))) - .andExpect(jsonPath("$.page.size", is(3))); + Matchers.containsString("page=" + (numberOfPages - 1)), + Matchers.containsString("size=" + pageSize)))) + .andExpect(jsonPath("$.page.totalElements", is(numberOfMdFields))) + .andExpect(jsonPath("$.page.totalPages", is(numberOfPages))) + .andExpect(jsonPath("$.page.size", is(pageSize))); + // Check second page getClient().perform(get("/api/core/metadatafields") - .param("size", "3") + .param("size", String.valueOf(pageSize)) .param("page", "1")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) + // Metadata fields are returned alphabetically. So, look for the next 3 alphabetically .andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItems( MetadataFieldMatcher.matchMetadataFieldByKeys("creativework","publisher", null), MetadataFieldMatcher.matchMetadataFieldByKeys("creativeworkseries", "issn", null), @@ -1004,48 +1018,53 @@ public class MetadatafieldRestRepositoryIT extends AbstractControllerIntegration ))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/core/metadatafields?"), - Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( Matchers.containsString("/api/core/metadatafields?"), - Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.self.href", Matchers.allOf( Matchers.containsString("/api/core/metadatafields?"), - Matchers.containsString("page=1"), Matchers.containsString("size=3")))) + Matchers.containsString("page=1"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.next.href", Matchers.allOf( Matchers.containsString("/api/core/metadatafields?"), - Matchers.containsString("page=2"), Matchers.containsString("size=3")))) + Matchers.containsString("page=2"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.last.href", Matchers.allOf( Matchers.containsString("/api/core/metadatafields?"), - Matchers.containsString("page=63"), Matchers.containsString("size=3")))) - .andExpect(jsonPath("$.page.totalElements", is(192))) - .andExpect(jsonPath("$.page.totalPages", is(64))) - .andExpect(jsonPath("$.page.size", is(3))); + Matchers.containsString("page=" + (numberOfPages - 1)), + Matchers.containsString("size=" + pageSize)))) + .andExpect(jsonPath("$.page.totalElements", is(numberOfMdFields))) + .andExpect(jsonPath("$.page.totalPages", is(numberOfPages))) + .andExpect(jsonPath("$.page.size", is(pageSize))); + // Check last page getClient().perform(get("/api/core/metadatafields") - .param("size", "3") - .param("page", "63")) + .param("size", String.valueOf(pageSize)) + .param("page", String.valueOf(numberOfPages - 1))) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) + // Metadata fields are returned alphabetically. + // So, on the last page we'll just ensure it *at least* includes the last field alphabetically .andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItems( - MetadataFieldMatcher.matchMetadataFieldByKeys("relation","isVolumeOfJournal", null), - MetadataFieldMatcher.matchMetadataFieldByKeys("relationship", "type", null), MetadataFieldMatcher.matchMetadataFieldByKeys("workflow", "score", null) ))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/core/metadatafields?"), - Matchers.containsString("page=0"), Matchers.containsString("size=3")))) + Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( Matchers.containsString("/api/core/metadatafields?"), - Matchers.containsString("page=62"), Matchers.containsString("size=3")))) + Matchers.containsString("page=" + (numberOfPages - 2)), + Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.self.href", Matchers.allOf( Matchers.containsString("/api/core/metadatafields?"), - Matchers.containsString("page=63"), Matchers.containsString("size=3")))) + Matchers.containsString("page=" + (numberOfPages - 1)), + Matchers.containsString("size=" + pageSize)))) .andExpect(jsonPath("$._links.last.href", Matchers.allOf( Matchers.containsString("/api/core/metadatafields?"), - Matchers.containsString("page=63"), Matchers.containsString("size=3")))) - .andExpect(jsonPath("$.page.totalElements", is(192))) - .andExpect(jsonPath("$.page.totalPages", is(64))) - .andExpect(jsonPath("$.page.size", is(3))); + Matchers.containsString("page=" + (numberOfPages - 1)), + Matchers.containsString("size=" + pageSize)))) + .andExpect(jsonPath("$.page.totalElements", is(numberOfMdFields))) + .andExpect(jsonPath("$.page.totalPages", is(numberOfPages))) + .andExpect(jsonPath("$.page.size", is(pageSize))); } } From 0597779b631a588337487c5136329b809407dbc9 Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Tue, 23 Mar 2021 09:36:01 +0100 Subject: [PATCH 175/179] 77817: Mark item as modified when adding to/removing from collection --- .../main/java/org/dspace/content/CollectionServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java index a25220967a..b6c2bab951 100644 --- a/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java @@ -612,6 +612,7 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i // Instead we add the collection to an item which works in the same way. if (!item.getCollections().contains(collection)) { item.addCollection(collection); + item.setModified(); } context.addEvent(new Event(Event.ADD, Constants.COLLECTION, collection.getID(), @@ -632,7 +633,7 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i } else { //Remove the item from the collection if we have multiple collections item.removeCollection(collection); - + item.setModified(); } context.addEvent(new Event(Event.REMOVE, Constants.COLLECTION, From 5cd9cc78025d996151ac27cf9182d5ac19c94b47 Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Tue, 23 Mar 2021 11:12:18 +0100 Subject: [PATCH 176/179] 77817: Add integration tests --- .../MappedCollectionRestRepositoryIT.java | 128 +++++++++++++++++- 1 file changed, 126 insertions(+), 2 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MappedCollectionRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MappedCollectionRestRepositoryIT.java index 26d5e87b1d..f38f5ced75 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MappedCollectionRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MappedCollectionRestRepositoryIT.java @@ -7,6 +7,7 @@ */ package org.dspace.app.rest; +import static org.hamcrest.Matchers.is; import static org.springframework.data.rest.webmvc.RestMediaTypes.TEXT_URI_LIST_VALUE; import static org.springframework.http.MediaType.parseMediaType; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; @@ -17,6 +18,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import org.dspace.app.rest.matcher.CollectionMatcher; import org.dspace.app.rest.matcher.ItemMatcher; +import org.dspace.app.rest.matcher.PageMatcher; +import org.dspace.app.rest.matcher.SearchResultMatcher; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; @@ -442,7 +445,7 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat getClient(adminToken) .perform(post("/api/core/items/" + publicItem1.getID() + "/mappedCollections/") .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) - .content("https://localhost:8080/spring-rest/api/core/collections/" + col1.getID() ) + .content("https://localhost:8080/spring-rest/api/core/collections/" + col1.getID()) ) .andExpect(status().isUnprocessableEntity()); } @@ -502,7 +505,7 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat getClient(adminToken) .perform(post("/api/core/items/" + templateItem.getID() + "/mappedCollections/") .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) - .content("https://localhost:8080/spring-rest/api/core/collections/" + col2.getID() ) + .content("https://localhost:8080/spring-rest/api/core/collections/" + col2.getID()) ) .andExpect(status().is(405)); } @@ -697,4 +700,125 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat } + @Test + public void mappedItemAppearsInCollectionBrowseTest() throws Exception { + context.turnOffAuthorisationSystem(); + + //** GIVEN ** + //1. A community-collection structure with one parent community with two collections. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection source = CollectionBuilder.createCollection(context, parentCommunity).withName("Source").build(); + Collection sink = CollectionBuilder.createCollection(context, parentCommunity).withName("Sink").build(); + + //2. An item in the source collection + Item item = ItemBuilder.createItem(context, source) + .withTitle("Mapped item") + .withIssueDate("2020") + .build(); + + context.restoreAuthSystemState(); + String adminToken = getAuthToken(admin.getEmail(), password); + + // Source collection browse is empty + getClient().perform( + get("/api/discover/search/objects") + .param("dsoType", "ITEM") + .param("scope", sink.getID().toString())) + // should return with 200 OK + .andExpect(status().isOk()) + // should contain no search results + .andExpect(jsonPath("$._embedded.searchResult.page", is( + PageMatcher.pageEntryWithTotalPagesAndElements(0, 20, 0, 0) + ))); + + // Map the item to the sink collection + getClient(adminToken).perform( + post("/api/core/items/" + item.getID() + "/mappedCollections/") + .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) + .content( + "https://localhost:8080/spring-rest/api/core/collections/" + sink.getID() + "\n" + ) + ); + + // Source collection browse contains mapped item + getClient().perform( + get("/api/discover/search/objects") + .param("dsoType", "ITEM") + .param("scope", sink.getID().toString())) + // should return with 200 OK + .andExpect(status().isOk()) + // should contain no search results + .andExpect(jsonPath("$._embedded.searchResult.page", is( + PageMatcher.pageEntryWithTotalPagesAndElements(0, 20, 1, 1) + ))) + // should match mapped item title + .andExpect(jsonPath("$._embedded.searchResult._embedded.objects", Matchers.containsInAnyOrder( + SearchResultMatcher.matchOnItemName("item", "items", "Mapped item") + ))); + } + + @Test + public void unmappedItemIsRemovedFromCollectionBrowseTest() throws Exception { + context.turnOffAuthorisationSystem(); + + //** GIVEN ** + //1. A community-collection structure with one parent community with two collections. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection source = CollectionBuilder.createCollection(context, parentCommunity).withName("Source").build(); + Collection sink = CollectionBuilder.createCollection(context, parentCommunity).withName("Sink").build(); + + //2. An item in the source collection + Item item = ItemBuilder.createItem(context, source) + .withTitle("Mapped item") + .withIssueDate("2020") + .build(); + + context.restoreAuthSystemState(); + String adminToken = getAuthToken(admin.getEmail(), password); + + //3. The item mapped to the sink collection + getClient(adminToken).perform( + post("/api/core/items/" + item.getID() + "/mappedCollections/") + .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) + .content( + "https://localhost:8080/spring-rest/api/core/collections/" + sink.getID() + "\n" + ) + ); + + // Source collection browse contains mapped item + getClient().perform( + get("/api/discover/search/objects") + .param("dsoType", "ITEM") + .param("scope", sink.getID().toString())) + // should return with 200 OK + .andExpect(status().isOk()) + // should contain no search results + .andExpect(jsonPath("$._embedded.searchResult.page", is( + PageMatcher.pageEntryWithTotalPagesAndElements(0, 20, 1, 1) + ))) + // should match mapped item title + .andExpect(jsonPath("$._embedded.searchResult._embedded.objects", Matchers.containsInAnyOrder( + SearchResultMatcher.matchOnItemName("item", "items", "Mapped item") + ))); + + // Unmap item from sink collection + getClient(adminToken).perform( + delete("/api/core/items/" + item.getID() + "/mappedCollections/" + sink.getID())); + + // Source collection browse is empty + getClient().perform( + get("/api/discover/search/objects") + .param("dsoType", "ITEM") + .param("scope", sink.getID().toString())) + // should return with 200 OK + .andExpect(status().isOk()) + // should contain no search results + .andExpect(jsonPath("$._embedded.searchResult.page", is( + PageMatcher.pageEntryWithTotalPagesAndElements(0, 20, 0, 0) + ))); + } } From 20dc0f6fbee854b32c302a1bfed7bf0dfb28eb5b Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Mon, 29 Mar 2021 09:06:54 +0200 Subject: [PATCH 177/179] Revert "77817: Mark item as modified when adding to/removing from collection" This reverts commit d80d26db --- .../main/java/org/dspace/content/CollectionServiceImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java index b6c2bab951..a25220967a 100644 --- a/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java @@ -612,7 +612,6 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i // Instead we add the collection to an item which works in the same way. if (!item.getCollections().contains(collection)) { item.addCollection(collection); - item.setModified(); } context.addEvent(new Event(Event.ADD, Constants.COLLECTION, collection.getID(), @@ -633,7 +632,7 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i } else { //Remove the item from the collection if we have multiple collections item.removeCollection(collection); - item.setModified(); + } context.addEvent(new Event(Event.REMOVE, Constants.COLLECTION, From 9b748790c8b5efc0743f6b7b323574575e3b66d2 Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Mon, 29 Mar 2021 09:29:58 +0200 Subject: [PATCH 178/179] 77817: Update mapped/unmapped Items in IndexEventConsumer --- .../main/java/org/dspace/discovery/IndexEventConsumer.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/discovery/IndexEventConsumer.java b/dspace-api/src/main/java/org/dspace/discovery/IndexEventConsumer.java index 6e008b15eb..7c50865970 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/IndexEventConsumer.java +++ b/dspace-api/src/main/java/org/dspace/discovery/IndexEventConsumer.java @@ -157,6 +157,12 @@ public class IndexEventConsumer implements Consumer { } else { log.debug("consume() adding event to update queue: " + event.toString()); objectsToUpdate.addAll(indexObjectServiceFactory.getIndexableObjects(ctx, subject)); + + // If the event subject is a Collection and the event object is an Item, + // also update the object in order to index mapped/unmapped Items + if (subject.getType() == Constants.COLLECTION && object.getType() == Constants.ITEM) { + objectsToUpdate.addAll(indexObjectServiceFactory.getIndexableObjects(ctx, object)); + } } break; From e23f2980e024de6de1cb20fee462fdb4413afdee Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Wed, 31 Mar 2021 10:49:01 +0200 Subject: [PATCH 179/179] 77817: Add subject null check --- .../src/main/java/org/dspace/discovery/IndexEventConsumer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/discovery/IndexEventConsumer.java b/dspace-api/src/main/java/org/dspace/discovery/IndexEventConsumer.java index 7c50865970..5f1f8b0b0e 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/IndexEventConsumer.java +++ b/dspace-api/src/main/java/org/dspace/discovery/IndexEventConsumer.java @@ -160,7 +160,8 @@ public class IndexEventConsumer implements Consumer { // If the event subject is a Collection and the event object is an Item, // also update the object in order to index mapped/unmapped Items - if (subject.getType() == Constants.COLLECTION && object.getType() == Constants.ITEM) { + if (subject != null && + subject.getType() == Constants.COLLECTION && object.getType() == Constants.ITEM) { objectsToUpdate.addAll(indexObjectServiceFactory.getIndexableObjects(ctx, object)); } }