From ef07aabbe1197c3bff5a8145be936fdddc43ff2b Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Mon, 20 Sep 2021 09:54:47 +0200 Subject: [PATCH 01/24] added tests for findByEntity collection end point --- .../app/rest/CollectionRestRepositoryIT.java | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) 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 09be02484f..2d19b0a4bb 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 @@ -14,7 +14,10 @@ import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadataDoesNotEx import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadataNotEmpty; import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadataStringEndsWith; import static org.dspace.core.Constants.WRITE; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.springframework.data.rest.webmvc.RestMediaTypes.TEXT_URI_LIST_VALUE; @@ -57,11 +60,13 @@ import org.dspace.authorize.service.ResourcePolicyService; 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; import org.dspace.content.Collection; import org.dspace.content.Community; +import org.dspace.content.EntityType; import org.dspace.content.Item; import org.dspace.content.service.CollectionService; import org.dspace.core.Constants; @@ -3200,4 +3205,162 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes .andExpect(jsonPath("$.page.totalElements", is(1))); } + @Test + public void findAuthorizedCollectionsByEntityType() throws Exception { + context.turnOffAuthorisationSystem(); + + EntityType journal = EntityTypeBuilder.createEntityTypeBuilder(context, "Journal").build(); + EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Community subCommunityA = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("SubCommunity A") + .build(); + + Community subCommunityB = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("SubCommunity B") + .build(); + + Collection col1 = CollectionBuilder.createCollection(context, subCommunityA) + .withEntityType(journal.getLabel()) + .withName("Collection 1") + .withAdminGroup(eperson) + .build(); + + Collection col2 = CollectionBuilder.createCollection(context, subCommunityB) + .withEntityType(journal.getLabel()) + .withName("Collection 2") + .withAdminGroup(eperson) + .build(); + + CollectionBuilder.createCollection(context, subCommunityA) + .withEntityType(publication.getLabel()) + .withName("Collection 3") + .withAdminGroup(eperson) + .build(); + + CollectionBuilder.createCollection(context, subCommunityA) + .withEntityType(journal.getLabel()) + .withName("Collection 4") + .build(); + + context.restoreAuthSystemState(); + + String ePersonToken = getAuthToken(eperson.getEmail(), password); + getClient(ePersonToken).perform(get("/api/core/collections/search/findSubmitAuthorizedByEntityType") + .param("entityType", journal.getLabel())) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.page.totalElements", equalTo(2))) + .andExpect(jsonPath("$._embedded.collections", containsInAnyOrder( + CollectionMatcher.matchCollection(col1), + CollectionMatcher.matchCollection(col2) + ))); + } + + @Test + public void findSubmitAuthorizedByEntityTypeNotFoundTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EntityType journal = EntityTypeBuilder.createEntityTypeBuilder(context, "Journal").build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType(journal.getLabel()) + .withName("Collection 1") + .withAdminGroup(eperson) + .build(); + + context.restoreAuthSystemState(); + + String ePersonToken = getAuthToken(eperson.getEmail(), password); + String adminToken = getAuthToken(eperson.getEmail(), password); + + getClient(ePersonToken).perform(get("/api/core/collections/search/findSubmitAuthorizedByEntityType") + .param("entityType", "test")) + .andExpect(status().isNotFound()); + + getClient(adminToken).perform(get("/api/core/collections/search/findSubmitAuthorizedByEntityType") + .param("entityType", "test")) + .andExpect(status().isNotFound()); + } + + @Test + public void findAuthorizedCollectionsByEntityTypeEmptyResponseTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + + context.restoreAuthSystemState(); + + String ePersonToken = getAuthToken(eperson.getEmail(), password); + getClient(ePersonToken).perform(get("/api/core/collections/search/findSubmitAuthorizedByEntityType") + .param("entityType", publication.getLabel())) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.page.totalElements", equalTo(0))); + } + + @Test + public void findAuthorizedCollectionsByEntityAndQueryType() throws Exception { + context.turnOffAuthorisationSystem(); + + EntityType journal = EntityTypeBuilder.createEntityTypeBuilder(context, "Journal").build(); + EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Community subCommunityA = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("SubCommunity A") + .build(); + + Community subCommunityB = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("SubCommunity B") + .build(); + + Collection col1 = CollectionBuilder.createCollection(context, subCommunityA) + .withEntityType(journal.getLabel()) + .withName("Thesis Collection") + .withAdminGroup(eperson) + .build(); + + CollectionBuilder.createCollection(context, subCommunityB) + .withEntityType(journal.getLabel()) + .withName("Work Collection") + .withAdminGroup(eperson) + .build(); + + CollectionBuilder.createCollection(context, subCommunityA) + .withEntityType(publication.getLabel()) + .withName("Thesis") + .withAdminGroup(eperson) + .build(); + + CollectionBuilder.createCollection(context, subCommunityA) + .withEntityType(journal.getLabel()) + .withName("Collection 1") + .build(); + + context.restoreAuthSystemState(); + + String ePersonToken = getAuthToken(eperson.getEmail(), password); + getClient(ePersonToken).perform(get("/api/core/collections/search/findSubmitAuthorizedByEntityType") + .param("entityType", journal.getLabel()) + .param("query", "Thesis")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.page.totalElements", equalTo(1))) + .andExpect(jsonPath("$._embedded.collections", contains( + CollectionMatcher.matchCollection(col1) + ))); + } + } From 25cfa7c750e120683fcb74568b81777ada45766e Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Mon, 20 Sep 2021 10:00:30 +0200 Subject: [PATCH 02/24] implemented findByEntityType collection end point --- .../dspace/content/CollectionServiceImpl.java | 85 +++++++++++++++++++ .../content/service/CollectionService.java | 41 +++++++++ .../CollectionIndexFactoryImpl.java | 2 + .../org/dspace/builder/CollectionBuilder.java | 4 + .../repository/CollectionRestRepository.java | 27 ++++++ dspace/solr/search/conf/schema.xml | 3 + 6 files changed, 162 insertions(+) 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 96ba571803..5b5d95ad87 100644 --- a/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java @@ -992,4 +992,89 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i DiscoverResult resp = searchService.search(context, discoverQuery); return resp; } + + /** + * Finds all Indexed Collections where the current user has submit rights. If the user is an Admin, + * this is all Indexed Collections. Otherwise, it includes those collections where + * an indexed "submit" policy lists either the eperson or one of the eperson's groups + * + * @param context DSpace context + * @param discoverQuery + * @param entityType limit the returned collection to those related to given entity type + * @param community parent community, could be null + * @param q limit the returned collection to those with metadata values matching the query + * terms. The terms are used to make also a prefix query on SOLR + * so it can be used to implement an autosuggest feature over the collection name + * @return discovery search result objects + * @throws SQLException if something goes wrong + * @throws SearchServiceException if search error + */ + private DiscoverResult retrieveCollectionsWithSubmit(Context context, DiscoverQuery discoverQuery, + String entityType, Community community, String q) + throws SQLException, SearchServiceException { + + StringBuilder query = new StringBuilder(); + EPerson currentUser = context.getCurrentUser(); + if (!authorizeService.isAdmin(context)) { + String userId = ""; + if (currentUser != null) { + userId = currentUser.getID().toString(); + } + query.append("submit:(e").append(userId); + + Set groups = groupService.allMemberGroupsSet(context, currentUser); + for (Group group : groups) { + query.append(" OR g").append(group.getID()); + } + query.append(")"); + discoverQuery.addFilterQueries(query.toString()); + } + StringBuilder buildFilter = new StringBuilder(); + if (community != null) { + buildFilter.append("location.comm:").append(community.getID().toString()); + } + if (StringUtils.isNotBlank(entityType)) { + if (buildFilter.length() > 0) { + buildFilter.append(" AND "); + } + buildFilter.append("dspace.entity.type:").append(entityType); + } + if (StringUtils.isNotBlank(q)) { + StringBuilder buildQuery = new StringBuilder(); + String escapedQuery = ClientUtils.escapeQueryChars(q); + buildQuery.append(escapedQuery).append(" OR ").append(escapedQuery).append("*"); + discoverQuery.setQuery(buildQuery.toString()); + } + discoverQuery.addFilterQueries(buildFilter.toString()); + DiscoverResult resp = searchService.search(context, discoverQuery); + return resp; + } + + @Override + public List findCollectionsWithSubmit(String q, Context context, Community community, String entityType, + int offset, int limit) throws SQLException, SearchServiceException { + List collections = new ArrayList<>(); + DiscoverQuery discoverQuery = new DiscoverQuery(); + discoverQuery.setDSpaceObjectFilter(IndexableCollection.TYPE); + discoverQuery.setStart(offset); + discoverQuery.setMaxResults(limit); + DiscoverResult resp = retrieveCollectionsWithSubmit(context, discoverQuery, + entityType, community, q); + for (IndexableObject solrCollections : resp.getIndexableObjects()) { + Collection c = ((IndexableCollection) solrCollections).getIndexedObject(); + collections.add(c); + } + return collections; + } + + @Override + public int countCollectionsWithSubmit(String q, Context context, Community community, String entityType) + throws SQLException, SearchServiceException { + DiscoverQuery discoverQuery = new DiscoverQuery(); + discoverQuery.setMaxResults(0); + discoverQuery.setDSpaceObjectFilter(IndexableCollection.TYPE); + DiscoverResult resp = retrieveCollectionsWithSubmit(context, discoverQuery, entityType, community, q); + return (int) resp.getTotalSearchResults(); + } + } diff --git a/dspace-api/src/main/java/org/dspace/content/service/CollectionService.java b/dspace-api/src/main/java/org/dspace/content/service/CollectionService.java index 67d45939d5..5c64ed532b 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/CollectionService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/CollectionService.java @@ -344,6 +344,27 @@ public interface CollectionService Group createDefaultReadGroup(Context context, Collection collection, String typeOfGroupString, int defaultRead) throws SQLException, AuthorizeException; + /** + * Returns Collections for which the current user has 'submit' privileges. + * NOTE: for better performance, this method retrieves its results from an + * index (cache) and does not query the database directly. + * This means that results may be stale or outdated until DS-4524 is resolved" + * + * @param q limit the returned collection to those with metadata values matching the query terms. + * The terms are used to make also a prefix query on SOLR so it can be used to implement + * an autosuggest feature over the collection name + * @param context DSpace Context + * @param community parent community + * @param entityType limit the returned collection to those related to given entity type + * @param offset the position of the first result to return + * @param limit paging limit + * @return discovery search result objects + * @throws SQLException if something goes wrong + * @throws SearchServiceException if search error + */ + public List findCollectionsWithSubmit(String q, Context context, Community community, + String entityType, int offset, int limit) throws SQLException, SearchServiceException; + /** * Returns Collections for which the current user has 'submit' privileges. * NOTE: for better performance, this method retrieves its results from an @@ -381,4 +402,24 @@ public interface CollectionService */ public int countCollectionsWithSubmit(String q, Context context, Community community) throws SQLException, SearchServiceException; + + /** + * Counts the number of Collection for which the current user has 'submit' privileges. + * NOTE: for better performance, this method retrieves its results from an index (cache) + * and does not query the database directly. + * This means that results may be stale or outdated until DS-4524 is resolved." + * + * @param q limit the returned collection to those with metadata values matching the query terms. + * The terms are used to make also a prefix query on SOLR so it can be used to implement + * an autosuggest feature over the collection name + * @param context DSpace Context + * @param community parent community + * @param entityType limit the returned collection to those related to given entity type + * @return total collections found + * @throws SQLException if something goes wrong + * @throws SearchServiceException if search error + */ + public int countCollectionsWithSubmit(String q, Context context, Community community, String entityType) + throws SQLException, SearchServiceException; + } diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/CollectionIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/CollectionIndexFactoryImpl.java index 5130be6cd7..f1bbcb8994 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/CollectionIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/CollectionIndexFactoryImpl.java @@ -111,6 +111,7 @@ public class CollectionIndexFactoryImpl extends DSpaceObjectIndexFactoryImpl toIgnoreMetadataFields = SearchUtils.getIgnoredMetadataFields(collection.getType()); addContainerMetadataField(doc, highlightedMetadataFields, toIgnoreMetadataFields, "dc.description", @@ -125,6 +126,7 @@ public class CollectionIndexFactoryImpl extends DSpaceObjectIndexFactoryImpl { return setMetadataSingleValue(collection, MetadataSchemaEnum.DC.getName(), "title", null, name); } + public CollectionBuilder withEntityType(final String entityType) { + return setMetadataSingleValue(collection, "dspace", "entity", "type", entityType); + } + /** * Set the name of the Collection in the given language. * diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java index 65d4ef4e6b..4a5d9f8e71 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java @@ -41,10 +41,12 @@ import org.dspace.authorize.service.AuthorizeService; 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.service.BitstreamService; import org.dspace.content.service.CollectionService; import org.dspace.content.service.CommunityService; +import org.dspace.content.service.EntityTypeService; import org.dspace.content.service.ItemService; import org.dspace.core.Constants; import org.dspace.core.Context; @@ -112,6 +114,9 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository findSubmitAuthorizedByEntityType( + @Parameter(value = "query") String query, + @Parameter(value = "entityType", required = true) String entityTypeLabel, + Pageable pageable) + throws SearchServiceException { + try { + Context context = obtainContext(); + EntityType entityType = this.entityTypeService.findByEntityType(context, entityTypeLabel); + if (entityType == null) { + throw new ResourceNotFoundException("There was no entityType found with label: " + entityTypeLabel); + } + List collections = cs.findCollectionsWithSubmit(query, context, null, entityTypeLabel, + Math.toIntExact(pageable.getOffset()), + Math.toIntExact(pageable.getOffset() + pageable.getPageSize())); + int tot = cs.countCollectionsWithSubmit(query, context, null, entityTypeLabel); + return converter.toRestPage(collections, pageable, tot, utils.obtainProjection()); + } catch (SQLException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + @Override @PreAuthorize("hasPermission(#id, 'COLLECTION', 'WRITE')") protected void patch(Context context, HttpServletRequest request, String apiCategory, String model, UUID id, diff --git a/dspace/solr/search/conf/schema.xml b/dspace/solr/search/conf/schema.xml index e16e213135..8df40c2728 100644 --- a/dspace/solr/search/conf/schema.xml +++ b/dspace/solr/search/conf/schema.xml @@ -263,6 +263,9 @@ + + + From 6433df2d9e4b1a27b7d49b378870d4c6f7a0243c Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Tue, 21 Sep 2021 17:33:45 +0200 Subject: [PATCH 03/24] implemented findSubmitAuthorizedByCommunityAndEntityType end point --- .../dspace/content/CollectionServiceImpl.java | 2 +- .../repository/CollectionRestRepository.java | 30 ++- .../app/rest/CollectionRestRepositoryIT.java | 180 ++++++++++++++++++ dspace/solr/search/conf/schema.xml | 3 +- 4 files changed, 212 insertions(+), 3 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 5b5d95ad87..2d9fabfdf7 100644 --- a/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java @@ -1037,7 +1037,7 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i if (buildFilter.length() > 0) { buildFilter.append(" AND "); } - buildFilter.append("dspace.entity.type:").append(entityType); + buildFilter.append("search.entitytype:").append(entityType); } if (StringUtils.isNotBlank(q)) { StringBuilder buildQuery = new StringBuilder(); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java index 4a5d9f8e71..36c53fd33c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java @@ -11,6 +11,7 @@ import java.io.IOException; import java.sql.SQLException; import java.util.LinkedList; import java.util.List; +import java.util.Objects; import java.util.SortedMap; import java.util.UUID; import javax.servlet.ServletInputStream; @@ -235,7 +236,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository collections = cs.findCollectionsWithSubmit(query, context, null, entityTypeLabel, Math.toIntExact(pageable.getOffset()), - Math.toIntExact(pageable.getOffset() + pageable.getPageSize())); + Math.toIntExact(pageable.getPageSize())); int tot = cs.countCollectionsWithSubmit(query, context, null, entityTypeLabel); return converter.toRestPage(collections, pageable, tot, utils.obtainProjection()); } catch (SQLException e) { @@ -243,6 +244,33 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository findSubmitAuthorizedByCommunityAndEntityType( + @Parameter(value = "query") String query, + @Parameter(value = "uuid", required = true) UUID communityUuid, + @Parameter(value = "entityType", required = true) String entityTypeLabel, + Pageable pageable) { + try { + Context context = obtainContext(); + EntityType entityType = entityTypeService.findByEntityType(context, entityTypeLabel); + if (Objects.isNull(entityType)) { + throw new ResourceNotFoundException("There was no entityType found with label: " + entityTypeLabel); + } + Community community = communityService.find(context, communityUuid); + if (Objects.isNull(community)) { + throw new ResourceNotFoundException( + CommunityRest.CATEGORY + "." + CommunityRest.NAME + " with id: " + communityUuid + " not found"); + } + List collections = cs.findCollectionsWithSubmit(query, context, community, entityTypeLabel, + Math.toIntExact(pageable.getOffset()), + Math.toIntExact(pageable.getPageSize())); + int total = cs.countCollectionsWithSubmit(query, context, community, entityTypeLabel); + return converter.toRestPage(collections, pageable, total, utils.obtainProjection()); + } catch (SQLException | SearchServiceException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + @Override @PreAuthorize("hasPermission(#id, 'COLLECTION', 'WRITE')") protected void patch(Context context, HttpServletRequest request, String apiCategory, String model, UUID id, 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 2d19b0a4bb..6d681dbf07 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 @@ -3363,4 +3363,184 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes ))); } + @Test + public void findSubmitAuthorizedCollectionsByCommunityAndEntityTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + + Community child2 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community Two") + .build(); + + CollectionBuilder.createCollection(context, child1) + .withEntityType(publication.getLabel()) + .withName("Test Collection 1") + .withSubmitterGroup(eperson) + .build(); + + Collection col2 = CollectionBuilder.createCollection(context, child2) + .withEntityType(publication.getLabel()) + .withName("Publication Collection 2") + .withSubmitterGroup(eperson) + .build(); + + Collection col3 = CollectionBuilder.createCollection(context, child2) + .withEntityType(publication.getLabel()) + .withName("Publication Collection 3") + .withSubmitterGroup(eperson) + .build(); + + Collection colWithoutEntity = CollectionBuilder.createCollection(context, child2) + .withName(" Test Collection 4") + .withSubmitterGroup(eperson) + .build(); + + context.restoreAuthSystemState(); + + String token = getAuthToken(eperson.getEmail(), password); + + getClient(token).perform(get("/api/core/collections/search/findSubmitAuthorizedByCommunityAndEntityType") + .param("uuid", child2.getID().toString()) + .param("entityType", publication.getLabel())) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.page.totalElements", equalTo(2))) + .andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder( + CollectionMatcher.matchCollection(col2), + CollectionMatcher.matchCollection(col3)))) + .andExpect(jsonPath("$._embedded.collections", not(containsInAnyOrder( + CollectionMatcher.matchCollection(colWithoutEntity))))); + } + + @Test + public void findSubmitAuthorizedCollectionsByCommunityAndEntityWithQueryTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EntityType journal = EntityTypeBuilder.createEntityTypeBuilder(context, "Journal").build(); + EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType(journal.getLabel()) + .withName("Test Collection 1") + .withSubmitterGroup(eperson) + .build(); + + Collection col2 = CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType(journal.getLabel()) + .withName("Publication Collection 2") + .withSubmitterGroup(eperson) + .build(); + + Collection col3 = CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType(publication.getLabel()) + .withName("Publication Collection 3 Test") + .withSubmitterGroup(eperson) + .build(); + + Collection colWithoutEntity = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 4 Test") + .withSubmitterGroup(eperson) + .build(); + + context.restoreAuthSystemState(); + + String token = getAuthToken(eperson.getEmail(), password); + getClient(token).perform(get("/api/core/collections/search/findSubmitAuthorizedByCommunityAndEntityType") + .param("uuid", parentCommunity.getID().toString()) + .param("entityType", journal.getLabel()) + .param("query", "test")) + .andExpect(status().isOk()).andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.page.totalElements", equalTo(1))) + .andExpect(jsonPath("$._embedded.collections", contains(CollectionMatcher.matchCollection(col1)))) + .andExpect(jsonPath("$._embedded.collections",not(contains( + CollectionMatcher.matchCollection(colWithoutEntity))))); + + getClient(token).perform(get("/api/core/collections/search/findSubmitAuthorizedByCommunityAndEntityType") + .param("uuid", parentCommunity.getID().toString()) + .param("entityType", publication.getLabel()) + .param("query", "publication")) + .andExpect(status().isOk()).andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.page.totalElements", equalTo(1))) + .andExpect(jsonPath("$._embedded.collections", contains(CollectionMatcher.matchCollection(col3)))) + .andExpect(jsonPath("$._embedded.collections", not(containsInAnyOrder( + CollectionMatcher.matchCollection(colWithoutEntity), + CollectionMatcher.matchCollection(col2))))); + } + + @Test + public void findSubmitAuthorizedAllCollectionsByCommunityAndEntityBadRequestTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType(publication.getLabel()) + .withName("Test Collection 1") + .withSubmitterGroup(eperson) + .build(); + + context.restoreAuthSystemState(); + + String token = getAuthToken(eperson.getEmail(), password); + getClient(token).perform(get("/api/core/collections/search/findSubmitAuthorizedByCommunityAndEntityType")) + .andExpect(status().isBadRequest()); + + // missing entityType param + getClient(token).perform(get("/api/core/collections/search/findSubmitAuthorizedByCommunityAndEntityType") + .param("uuid", parentCommunity.getID().toString())) + .andExpect(status().isBadRequest()); + + // missing community uuid param + getClient(token).perform(get("/api/core/collections/search/findSubmitAuthorizedByCommunityAndEntityType") + .param("entityType", publication.getLabel())) + .andExpect(status().isBadRequest()); + } + + @Test + public void findSubmitAuthorizedByCommunityAndEntityTypeNotFoundTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType(publication.getLabel()) + .withName("Test Collection 1") + .withSubmitterGroup(eperson) + .build(); + + context.restoreAuthSystemState(); + + String token = getAuthToken(eperson.getEmail(), password); + getClient(token).perform(get("/api/core/collections/search/findSubmitAuthorizedByCommunityAndEntityType") + .param("entityType", publication.getLabel()) + .param("uuid", UUID.randomUUID().toString())) + .andExpect(status().isNotFound()); + + getClient(token).perform(get("/api/core/collections/search/findSubmitAuthorizedByCommunityAndEntityType") + .param("entityType", "test") + .param("uuid", parentCommunity.getID().toString())) + .andExpect(status().isNotFound()); + } + } diff --git a/dspace/solr/search/conf/schema.xml b/dspace/solr/search/conf/schema.xml index 8df40c2728..09eeb173e2 100644 --- a/dspace/solr/search/conf/schema.xml +++ b/dspace/solr/search/conf/schema.xml @@ -265,7 +265,7 @@ - + @@ -345,5 +345,6 @@ or to add multiple fields to the same field for easier/faster searching. --> + From a3a1019db7ae9fbd397da9496260462f621a69ad Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Tue, 21 Sep 2021 18:56:39 +0200 Subject: [PATCH 04/24] implemented entityType and externalSources end points and tests --- .../dspace/content/EntityTypeServiceImpl.java | 58 +++++ .../content/service/EntityTypeService.java | 5 + .../AbstractExternalDataProvider.java | 43 ++++ .../provider/ExternalDataProvider.java | 12 + .../provider/impl/LiveImportDataProvider.java | 4 +- .../impl/OrcidV3AuthorDataProvider.java | 10 +- .../impl/SHERPAv2JournalDataProvider.java | 7 +- .../impl/SHERPAv2JournalISSNDataProvider.java | 4 +- .../impl/SHERPAv2PublisherDataProvider.java | 9 +- .../external/service/ExternalDataService.java | 21 ++ .../service/impl/ExternalDataServiceImpl.java | 13 +- .../config/spring/api/external-services.xml | 20 ++ .../provider/impl/MockDataProvider.java | 4 +- .../repository/EntityTypeRestRepository.java | 55 +++++ .../ExternalSourceRestRepository.java | 15 ++ .../app/rest/EntityTypeRestRepositoryIT.java | 233 +++++++++++++++++- .../rest/ExternalSourcesRestControllerIT.java | 57 +++++ .../provider/impl/MockDataProvider.java | 4 +- 18 files changed, 543 insertions(+), 31 deletions(-) create mode 100644 dspace-api/src/main/java/org/dspace/external/provider/AbstractExternalDataProvider.java diff --git a/dspace-api/src/main/java/org/dspace/content/EntityTypeServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/EntityTypeServiceImpl.java index 4577054ff0..f3e156dd42 100644 --- a/dspace-api/src/main/java/org/dspace/content/EntityTypeServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/EntityTypeServiceImpl.java @@ -7,16 +7,30 @@ */ package org.dspace.content; +import java.io.IOException; import java.sql.SQLException; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; +import java.util.Set; import org.apache.commons.collections.CollectionUtils; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.response.FacetField; +import org.apache.solr.client.solrj.response.FacetField.Count; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.params.FacetParams; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.service.AuthorizeService; import org.dspace.content.dao.EntityTypeDAO; import org.dspace.content.service.EntityTypeService; import org.dspace.core.Context; +import org.dspace.discovery.SolrSearchCore; +import org.dspace.discovery.indexobject.IndexableCollection; +import org.dspace.eperson.Group; +import org.dspace.eperson.service.GroupService; import org.springframework.beans.factory.annotation.Autowired; public class EntityTypeServiceImpl implements EntityTypeService { @@ -27,6 +41,12 @@ public class EntityTypeServiceImpl implements EntityTypeService { @Autowired(required = true) protected AuthorizeService authorizeService; + @Autowired + protected GroupService groupService; + + @Autowired + protected SolrSearchCore solrSearchCore; + @Override public EntityType findByEntityType(Context context, String entityType) throws SQLException { return entityTypeDAO.findByEntityType(context, entityType); @@ -98,4 +118,42 @@ public class EntityTypeServiceImpl implements EntityTypeService { } entityTypeDAO.delete(context, entityType); } + + @Override + public List getSubmitAuthorizedTypes(Context context) + throws SQLException, SolrServerException, IOException { + List types = new ArrayList<>(); + StringBuilder query = new StringBuilder(); + org.dspace.eperson.EPerson currentUser = context.getCurrentUser(); + if (!authorizeService.isAdmin(context)) { + String userId = ""; + if (currentUser != null) { + userId = currentUser.getID().toString(); + } + query.append("submit:(e").append(userId); + Set groups = groupService.allMemberGroupsSet(context, currentUser); + for (Group group : groups) { + query.append(" OR g").append(group.getID()); + } + query.append(")"); + } else { + query.append("*:*"); + } + + SolrQuery sQuery = new SolrQuery(query.toString()); + sQuery.addFilterQuery("search.resourcetype:" + IndexableCollection.TYPE); + sQuery.setRows(0); + sQuery.addFacetField("search.entitytype"); + sQuery.setFacetMinCount(1); + sQuery.setFacetLimit(Integer.MAX_VALUE); + sQuery.setFacetSort(FacetParams.FACET_SORT_INDEX); + QueryResponse qResp = solrSearchCore.getSolr().query(sQuery); + FacetField facetField = qResp.getFacetField("search.entitytype"); + if (Objects.nonNull(facetField)) { + for (Count c : facetField.getValues()) { + types.add(c.getName()); + } + } + return types; + } } diff --git a/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java b/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java index f4d9a15bb2..b06bc34c50 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java @@ -7,9 +7,11 @@ */ package org.dspace.content.service; +import java.io.IOException; import java.sql.SQLException; import java.util.List; +import org.apache.solr.client.solrj.SolrServerException; import org.dspace.authorize.AuthorizeException; import org.dspace.content.EntityType; import org.dspace.core.Context; @@ -56,4 +58,7 @@ public interface EntityTypeService extends DSpaceCRUDService { * @throws AuthorizeException If something geos wrong with authorizations */ public EntityType create(Context context, String entityTypeString) throws SQLException, AuthorizeException; + + public List getSubmitAuthorizedTypes(Context context) throws SQLException, SolrServerException, IOException; + } diff --git a/dspace-api/src/main/java/org/dspace/external/provider/AbstractExternalDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/AbstractExternalDataProvider.java new file mode 100644 index 0000000000..e08481e377 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/external/provider/AbstractExternalDataProvider.java @@ -0,0 +1,43 @@ +/** + * 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; +import java.util.List; +import java.util.Objects; + +/** + * This abstract class allows to configure the list of supported entity types + * via spring. If no entity types are explicitly configured it is assumed that + * the provider can be used with any entity type + * + * @author Mykhaylo Boychuk (mykhaylo.boychuk at 4science.it) + */ +public abstract class AbstractExternalDataProvider implements ExternalDataProvider { + + private List supportedEntityTypes; + + public void setSupportedEntityTypes(List supportedEntityTypes) { + this.supportedEntityTypes = supportedEntityTypes; + } + + public List getSupportedEntityTypes() { + return supportedEntityTypes; + } + + /** + * Return true if the supportedEntityTypes list is empty or contains the requested entity type + * + * @param entityType the entity type to check + * @return true if the external provider can be used to search for items of the + * specified type + */ + @Override + public boolean supportsEntityType(String entityType) { + return Objects.isNull(supportedEntityTypes) || supportedEntityTypes.contains(entityType); + } + +} \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/external/provider/ExternalDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/ExternalDataProvider.java index 5c921efd35..1227b4b2ff 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/ExternalDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/ExternalDataProvider.java @@ -57,4 +57,16 @@ public interface ExternalDataProvider { */ public int getNumberOfResults(String query); + /** + * Override this method to limit the external data provider to specific entity + * types (Publication, OrgUnit, etc.) + * + * @param entityType the entity type to check + * @return true if the external provider can be used to search for items of the + * specified type + */ + public default boolean supportsEntityType(String entityType) { + return true; + } + } diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/LiveImportDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/LiveImportDataProvider.java index 45855a74ad..962183fa6f 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/LiveImportDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/LiveImportDataProvider.java @@ -15,7 +15,7 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.dspace.content.dto.MetadataValueDTO; import org.dspace.external.model.ExternalDataObject; -import org.dspace.external.provider.ExternalDataProvider; +import org.dspace.external.provider.AbstractExternalDataProvider; import org.dspace.importer.external.datamodel.ImportRecord; import org.dspace.importer.external.exception.MetadataSourceException; import org.dspace.importer.external.metadatamapping.MetadatumDTO; @@ -27,7 +27,7 @@ import org.dspace.importer.external.service.components.QuerySource; * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class LiveImportDataProvider implements ExternalDataProvider { +public class LiveImportDataProvider extends AbstractExternalDataProvider { /** * The {@link QuerySource} live import provider */ diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/OrcidV3AuthorDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/OrcidV3AuthorDataProvider.java index 629ff3829d..0653ee758d 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/OrcidV3AuthorDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/OrcidV3AuthorDataProvider.java @@ -16,6 +16,7 @@ import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -29,7 +30,7 @@ import org.apache.logging.log4j.Logger; import org.dspace.content.dto.MetadataValueDTO; import org.dspace.external.OrcidRestConnector; import org.dspace.external.model.ExternalDataObject; -import org.dspace.external.provider.ExternalDataProvider; +import org.dspace.external.provider.AbstractExternalDataProvider; import org.dspace.external.provider.orcid.xml.XMLtoBio; import org.json.JSONObject; import org.orcid.jaxb.model.v3.release.common.OrcidIdentifier; @@ -41,7 +42,7 @@ import org.springframework.beans.factory.annotation.Autowired; * This class is the implementation of the ExternalDataProvider interface that will deal with the OrcidV3 External * Data lookup */ -public class OrcidV3AuthorDataProvider implements ExternalDataProvider { +public class OrcidV3AuthorDataProvider extends AbstractExternalDataProvider { private static final Logger log = LogManager.getLogger(OrcidV3AuthorDataProvider.class); @@ -217,11 +218,10 @@ public class OrcidV3AuthorDataProvider implements ExternalDataProvider { } catch (IOException e) { log.error(e.getMessage(), e); } - if (bios == null) { + if (Objects.isNull(bios)) { return Collections.emptyList(); - } else { - return bios.stream().map(bio -> convertToExternalDataObject(bio)).collect(Collectors.toList()); } + return bios.stream().map(bio -> convertToExternalDataObject(bio)).collect(Collectors.toList()); } @Override 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 42d3cab494..a4276c83ed 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,14 +15,13 @@ 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; +import org.dspace.external.provider.AbstractExternalDataProvider; /** * This class is the implementation of the ExternalDataProvider interface that will deal with SherpaJournal External @@ -31,9 +30,7 @@ import org.dspace.external.provider.ExternalDataProvider; * * @author Kim Shepherd */ -public class SHERPAv2JournalDataProvider implements ExternalDataProvider { - - private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(SHERPAv2JournalDataProvider.class); +public class SHERPAv2JournalDataProvider extends AbstractExternalDataProvider { // Source identifier (configured in spring configuration) private String sourceIdentifier; 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 index ed2df53c83..9e61b9ac2a 100644 --- 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 @@ -22,7 +22,7 @@ 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.external.provider.AbstractExternalDataProvider; /** * This class is the implementation of the ExternalDataProvider interface that will deal with SherpaJournal External @@ -32,7 +32,7 @@ import org.dspace.external.provider.ExternalDataProvider; * * @author Kim Shepherd */ -public class SHERPAv2JournalISSNDataProvider implements ExternalDataProvider { +public class SHERPAv2JournalISSNDataProvider extends AbstractExternalDataProvider { private static final Logger log = org.apache.logging.log4j.LogManager.getLogger( 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 03f172853e..af922220ce 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 @@ -15,14 +15,13 @@ 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.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.external.provider.AbstractExternalDataProvider; /** * This class is the implementation of the ExternalDataProvider interface that will deal with SHERPAPublisher External @@ -33,11 +32,7 @@ import org.dspace.external.provider.ExternalDataProvider; * * @author Kim Shepherd */ -public class SHERPAv2PublisherDataProvider implements ExternalDataProvider { - - // Logger - private static final Logger log = - org.apache.logging.log4j.LogManager.getLogger(SHERPAv2PublisherDataProvider.class); +public class SHERPAv2PublisherDataProvider extends AbstractExternalDataProvider { // Source identifier (eg 'sherpaPublisher') configured in spring configuration private String sourceIdentifier; diff --git a/dspace-api/src/main/java/org/dspace/external/service/ExternalDataService.java b/dspace-api/src/main/java/org/dspace/external/service/ExternalDataService.java index e0c241ba4a..53423395e3 100644 --- a/dspace-api/src/main/java/org/dspace/external/service/ExternalDataService.java +++ b/dspace-api/src/main/java/org/dspace/external/service/ExternalDataService.java @@ -77,4 +77,25 @@ public interface ExternalDataService { WorkspaceItem createWorkspaceItemFromExternalDataObject(Context context, ExternalDataObject externalDataObject, Collection collection) throws AuthorizeException, SQLException; + + /** + * Return the ExternalDataProvider that supports a specific entity type + * + * @param entityType + * @return list of ExternalDataProviders that supports a specific entity type + */ + public List getExternalDataProvidersForEntityType(String entityType); + + /** + * Override this method to limit the external data provider to specific entity + * types (Publication, OrgUnit, etc.) + * + * @param entityType the entity type to check + * @return true if the external provider can be used to search for items of the + * specified type + */ + public default boolean supportsEntityType(String entityType) { + return true; + } + } diff --git a/dspace-api/src/main/java/org/dspace/external/service/impl/ExternalDataServiceImpl.java b/dspace-api/src/main/java/org/dspace/external/service/impl/ExternalDataServiceImpl.java index 227a31e6fb..f91ea00cac 100644 --- a/dspace-api/src/main/java/org/dspace/external/service/impl/ExternalDataServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/external/service/impl/ExternalDataServiceImpl.java @@ -10,10 +10,10 @@ package org.dspace.external.service.impl; import java.sql.SQLException; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; import org.apache.logging.log4j.Logger; import org.dspace.authorize.AuthorizeException; -import org.dspace.authorize.service.AuthorizeService; import org.dspace.content.Collection; import org.dspace.content.Item; import org.dspace.content.WorkspaceItem; @@ -44,9 +44,6 @@ public class ExternalDataServiceImpl implements ExternalDataService { @Autowired private WorkspaceItemService workspaceItemService; - @Autowired - private AuthorizeService authorizeService; - @Override public Optional getExternalDataObject(String source, String id) { ExternalDataProvider provider = getExternalDataProvider(source); @@ -110,4 +107,12 @@ public class ExternalDataServiceImpl implements ExternalDataService { externalDataObject.getId())); return workspaceItem; } + + @Override + public List getExternalDataProvidersForEntityType(String entityType) { + return externalDataProviders.stream() + .filter(edp -> edp.supportsEntityType(entityType)) + .collect(Collectors.toList()); + } + } 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 590fd57cb6..cf36e7fd25 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 @@ -20,6 +20,11 @@ + + + Journal + + @@ -30,6 +35,11 @@ + + + Journal + + @@ -40,6 +50,11 @@ + + + OrgUnit + + @@ -48,6 +63,11 @@ + + + Publication + + diff --git a/dspace-api/src/test/java/org/dspace/external/provider/impl/MockDataProvider.java b/dspace-api/src/test/java/org/dspace/external/provider/impl/MockDataProvider.java index e5a86f1f56..cdfbf1e943 100644 --- a/dspace-api/src/test/java/org/dspace/external/provider/impl/MockDataProvider.java +++ b/dspace-api/src/test/java/org/dspace/external/provider/impl/MockDataProvider.java @@ -17,9 +17,9 @@ import java.util.Optional; import org.apache.commons.lang3.StringUtils; import org.dspace.content.dto.MetadataValueDTO; import org.dspace.external.model.ExternalDataObject; -import org.dspace.external.provider.ExternalDataProvider; +import org.dspace.external.provider.AbstractExternalDataProvider; -public class MockDataProvider implements ExternalDataProvider { +public class MockDataProvider extends AbstractExternalDataProvider { private Map mockLookupMap; private String sourceIdentifier; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java index 29db39d879..341a8111e3 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java @@ -7,13 +7,20 @@ */ package org.dspace.app.rest.repository; +import java.io.IOException; import java.sql.SQLException; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import org.apache.commons.lang.StringUtils; +import org.apache.solr.client.solrj.SolrServerException; +import org.dspace.app.rest.SearchRestMethod; import org.dspace.app.rest.model.EntityTypeRest; import org.dspace.content.EntityType; import org.dspace.content.service.EntityTypeService; import org.dspace.core.Context; +import org.dspace.external.service.ExternalDataService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -29,6 +36,8 @@ public class EntityTypeRestRepository extends DSpaceRestRepository findAllByAuthorizedCollection(Pageable pageable) { + try { + Context context = obtainContext(); + List types = entityTypeService.getSubmitAuthorizedTypes(context); + List entityTypes = types.stream().map(type -> { + if (StringUtils.isBlank(type)) { + return null; + } + try { + return entityTypeService.findByEntityType(context, type); + } catch (SQLException e) { + throw new RuntimeException(e.getMessage(), e); + } + }).filter(x -> Objects.nonNull(x)).collect(Collectors.toList()); + return converter.toRestPage(entityTypes, pageable, utils.obtainProjection()); + } catch (SQLException | SolrServerException | IOException e) { + throw new RuntimeException(e); + } + } + + @SearchRestMethod(name = "findAllByAuthorizedExternalSource") + public Page findAllByAuthorizedExternalSource(Pageable pageable) { + try { + Context context = obtainContext(); + List types = entityTypeService.getSubmitAuthorizedTypes(context); + List entityTypes = types.stream() + .filter(x -> externalDataService.getExternalDataProvidersForEntityType(x).size() > 0) + .map(type -> { + if (StringUtils.isBlank(type)) { + return null; + } + try { + return entityTypeService.findByEntityType(context, type); + } catch (SQLException e) { + throw new RuntimeException(e.getMessage(), e); + } + }) + .filter(x -> Objects.nonNull(x)) + .collect(Collectors.toList()); + return converter.toRestPage(entityTypes, pageable, utils.obtainProjection()); + } catch (SQLException | SolrServerException | IOException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + @Override public Class getDomainClass() { return EntityTypeRest.class; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalSourceRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalSourceRestRepository.java index 4a24d4e10e..474264520b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalSourceRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalSourceRestRepository.java @@ -9,7 +9,10 @@ package org.dspace.app.rest.repository; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; +import org.dspace.app.rest.Parameter; +import org.dspace.app.rest.SearchRestMethod; import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.ExternalSourceEntryRest; import org.dspace.app.rest.model.ExternalSourceRest; @@ -96,6 +99,18 @@ public class ExternalSourceRestRepository extends DSpaceRestRepository findByEntityType(Context context, Pageable pageable, + @Parameter(required = true, value = "entityType") String entityType) { + List externalSources = externalDataService.getExternalDataProviders() + .stream() + .filter(ep -> ep.supportsEntityType(entityType)) + .collect(Collectors.toList()); + + return converter.toRestPage(externalSources, pageable, utils.obtainProjection()); + } + public Class getDomainClass() { return ExternalSourceRest.class; } 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 0f6060c011..5ab815ef6d 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 @@ -6,7 +6,7 @@ * http://www.dspace.org/license/ */ package org.dspace.app.rest; - +import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; @@ -14,17 +14,31 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import java.util.Arrays; + import org.dspace.app.rest.matcher.EntityTypeMatcher; import org.dspace.app.rest.test.AbstractEntityIntegrationTest; +import org.dspace.builder.CollectionBuilder; +import org.dspace.builder.CommunityBuilder; +import org.dspace.builder.EntityTypeBuilder; +import org.dspace.content.Community; import org.dspace.content.EntityType; import org.dspace.content.service.EntityTypeService; +import org.dspace.external.provider.AbstractExternalDataProvider; +import org.dspace.external.service.ExternalDataService; import org.hamcrest.Matchers; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; +/** + * Integration test class for the entity type endpoint + * + * @author Mykhaylo Boychuk - 4Science + */ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { - + @Autowired + private ExternalDataService externalDataService; @Autowired private EntityTypeService entityTypeService; @@ -168,4 +182,219 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { .andExpect(jsonPath("$.page.number", is(1))); } + @Test + public void findAllByAuthorizedCollectionTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType("JournalIssue") + .withSubmitterGroup(eperson) + .withName("Collection 1") + .build(); + + CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType("Publication") + .withSubmitterGroup(eperson) + .withName("Collection 2") + .build(); + + CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType("Project") + .withSubmitterGroup(eperson) + .withName("Collection 3") + .build(); + + CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType("Journal") + .withSubmitterGroup(eperson) + .withName("Collection 4") + .build(); + + context.restoreAuthSystemState(); + + String token = getAuthToken(eperson.getEmail(), password); + getClient(token).perform(get("/api/core/entitytypes/search/findAllByAuthorizedCollection")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "JournalIssue")), + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Publication")), + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Project")), + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Journal")) + ))); + } + + @Test + public void findAllByAuthorizedCollectionPaginationTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType("JournalIssue") + .withSubmitterGroup(eperson) + .withName("Collection 1") + .build(); + + CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType("Publication") + .withSubmitterGroup(eperson) + .withName("Collection 2") + .build(); + + CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType("Project") + .withSubmitterGroup(eperson) + .withName("Collection 3") + .build(); + + CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType("Journal") + .withSubmitterGroup(eperson) + .withName("Collection 4") + .build(); + + context.restoreAuthSystemState(); + + String token = getAuthToken(eperson.getEmail(), password); + getClient(token).perform(get("/api/core/entitytypes/search/findAllByAuthorizedCollection") + .param("size", "2")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "JournalIssue")), + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Journal")) + ))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("api/core/entitytypes/search/findAllByAuthorizedCollection?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("api/core/entitytypes/search/findAllByAuthorizedCollection?"), + Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.next.href", Matchers.allOf( + Matchers.containsString("api/core/entitytypes/search/findAllByAuthorizedCollection?"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("api/core/entitytypes/search/findAllByAuthorizedCollection?"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$.page.size", is(2))) + .andExpect(jsonPath("$.page.totalElements", is(4))) + .andExpect(jsonPath("$.page.totalPages", is(2))) + .andExpect(jsonPath("$.page.number", is(0))); + + getClient(token).perform(get("/api/core/entitytypes/search/findAllByAuthorizedCollection") + .param("page", "1") + .param("size", "2")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Publication")), + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Project")) + ))) + .andExpect(jsonPath("$._links.first.href", Matchers.allOf( + Matchers.containsString("api/core/entitytypes/search/findAllByAuthorizedCollection?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.self.href", Matchers.allOf( + Matchers.containsString("api/core/entitytypes/search/findAllByAuthorizedCollection?"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( + Matchers.containsString("api/core/entitytypes/search/findAllByAuthorizedCollection?"), + Matchers.containsString("page=0"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.last.href", Matchers.allOf( + Matchers.containsString("api/core/entitytypes/search/findAllByAuthorizedCollection?"), + Matchers.containsString("page=1"), Matchers.containsString("size=2")))) + .andExpect(jsonPath("$.page.size", is(2))) + .andExpect(jsonPath("$.page.totalElements", is(4))) + .andExpect(jsonPath("$.page.totalPages", is(2))) + .andExpect(jsonPath("$.page.number", is(1))); + } + + @Test + public void findAllByAuthorizedExternalSource() throws Exception { + context.turnOffAuthorisationSystem(); + + EntityType publication = entityTypeService.findByEntityType(context, "Publication"); + EntityType orgUnit = entityTypeService.findByEntityType(context, "OrgUnit"); + EntityType project = entityTypeService.findByEntityType(context, "Project"); + EntityType funding = EntityTypeBuilder.createEntityTypeBuilder(context, "Funding").build(); + + Community rootCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + CollectionBuilder.createCollection(context, rootCommunity) + .withEntityType(orgUnit.getLabel()) + .withName("Collection 1") + .build(); + + CollectionBuilder.createCollection(context, rootCommunity) + .withEntityType(publication.getLabel()) + .withSubmitterGroup(eperson) + .withName("Collection 2") + .build(); + + CollectionBuilder.createCollection(context, rootCommunity) + .withEntityType(project.getLabel()) + .withSubmitterGroup(eperson) + .withName("Collection 3") + .build(); + + CollectionBuilder.createCollection(context, rootCommunity) + .withEntityType(funding.getLabel()) + .withSubmitterGroup(eperson) + .withName("Collection 4") + .build(); + + context.restoreAuthSystemState(); + + String token = getAuthToken(eperson.getEmail(), password); + getClient(token).perform(get("/api/core/entitytypes/search/findAllByAuthorizedExternalSource")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(publication), + EntityTypeMatcher.matchEntityTypeEntry(funding), + EntityTypeMatcher.matchEntityTypeEntry(project)))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(3))); + + String adminToken = getAuthToken(admin.getEmail(), password); + getClient(adminToken).perform(get("/api/core/entitytypes/search/findAllByAuthorizedExternalSource")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(orgUnit), + EntityTypeMatcher.matchEntityTypeEntry(funding), + EntityTypeMatcher.matchEntityTypeEntry(project), + EntityTypeMatcher.matchEntityTypeEntry(publication)))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(4))); + + try { + ((AbstractExternalDataProvider) externalDataService.getExternalDataProvider("mock")) + .setSupportedEntityTypes(Arrays.asList("Publication")); + ((AbstractExternalDataProvider) externalDataService.getExternalDataProvider("pubmed")) + .setSupportedEntityTypes(Arrays.asList("Publication")); + + getClient(token).perform(get("/api/core/entitytypes/search/findAllByAuthorizedExternalSource")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.entitytypes", contains( + EntityTypeMatcher.matchEntityTypeEntry(publication)))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(1))); + + getClient(adminToken).perform(get("/api/core/entitytypes/search/findAllByAuthorizedExternalSource")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(orgUnit), + EntityTypeMatcher.matchEntityTypeEntry(publication)))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(2))); + + } finally { + ((AbstractExternalDataProvider) externalDataService.getExternalDataProvider("mock")) + .setSupportedEntityTypes(null); + ((AbstractExternalDataProvider) externalDataService.getExternalDataProvider("pubmed")) + .setSupportedEntityTypes(null); + } + + } + } \ No newline at end of file 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 3497942be3..484171fcb6 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 @@ -125,4 +125,61 @@ public class ExternalSourcesRestControllerIT extends AbstractControllerIntegrati getClient().perform(get("/api/integration/externalsources/mock/entries")) .andExpect(status().isBadRequest()); } + + @Test + public void findExternalSourcesByEntityTypeTest() throws Exception { + getClient().perform(get("/api/integration/externalsources/search/findByEntityType") + .param("entityType", "Publication")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.externalsources", Matchers.contains( + ExternalSourceMatcher.matchExternalSource("mock", "mock", false), + ExternalSourceMatcher.matchExternalSource("orcid", "orcid", false), + ExternalSourceMatcher.matchExternalSource("pubmed", "pubmed", false) + ))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(3))); + + getClient().perform(get("/api/integration/externalsources/search/findByEntityType") + .param("entityType", "Journal")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.externalsources", Matchers.contains( + ExternalSourceMatcher.matchExternalSource("mock", "mock", false), + ExternalSourceMatcher.matchExternalSource("sherpaJournalIssn", "sherpaJournalIssn",false), + ExternalSourceMatcher.matchExternalSource("sherpaJournal", "sherpaJournal", false), + ExternalSourceMatcher.matchExternalSource("pubmed", "pubmed", false) + ))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(4))); + } + + @Test + public void findExternalSourcesByEntityTypeBadRequestTest() throws Exception { + getClient().perform(get("/api/integration/externalsources/search/findByEntityType")) + .andExpect(status().isBadRequest()); + } + + @Test + public void findExternalSourcesByEntityTypePaginationTest() throws Exception { + getClient().perform(get("/api/integration/externalsources/search/findByEntityType") + .param("entityType", "Journal") + .param("size", "2")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.externalsources", Matchers.contains( + ExternalSourceMatcher.matchExternalSource("mock", "mock", false), + ExternalSourceMatcher.matchExternalSource("sherpaJournalIssn", "sherpaJournalIssn",false) + ))) + .andExpect(jsonPath("$.page.totalPages", Matchers.is(2))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(4))); + + getClient().perform(get("/api/integration/externalsources/search/findByEntityType") + .param("entityType", "Journal") + .param("page", "1") + .param("size", "2")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.externalsources", Matchers.contains( + ExternalSourceMatcher.matchExternalSource("sherpaJournal", "sherpaJournal", false), + ExternalSourceMatcher.matchExternalSource("pubmed", "pubmed", false) + ))) + .andExpect(jsonPath("$.page.totalPages", Matchers.is(2))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(4))); + } + } diff --git a/dspace-server-webapp/src/test/java/org/dspace/external/provider/impl/MockDataProvider.java b/dspace-server-webapp/src/test/java/org/dspace/external/provider/impl/MockDataProvider.java index b8dc7b501b..894b8e409a 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/external/provider/impl/MockDataProvider.java +++ b/dspace-server-webapp/src/test/java/org/dspace/external/provider/impl/MockDataProvider.java @@ -17,9 +17,9 @@ import java.util.Optional; import org.apache.commons.lang3.StringUtils; import org.dspace.content.dto.MetadataValueDTO; import org.dspace.external.model.ExternalDataObject; -import org.dspace.external.provider.ExternalDataProvider; +import org.dspace.external.provider.AbstractExternalDataProvider; -public class MockDataProvider implements ExternalDataProvider { +public class MockDataProvider extends AbstractExternalDataProvider { private Map mockLookupMap; private String sourceIdentifier; From 82ff056681e22fd8e6b7d06a29a6f098219578a5 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Wed, 22 Sep 2021 18:07:23 +0200 Subject: [PATCH 05/24] implemented endpoint that is able to retrieve supported entity types provided an external provider and tests --- .../dspace/content/EntityTypeServiceImpl.java | 12 ++ .../org/dspace/content/dao/EntityTypeDAO.java | 22 ++++ .../content/dao/impl/EntityTypeDAOImpl.java | 27 ++++ .../content/service/EntityTypeService.java | 21 +++ .../app/rest/model/ExternalSourceRest.java | 9 ++ ...xternalSourceEntityTypeLinkRepository.java | 73 +++++++++++ .../rest/ExternalSourcesRestControllerIT.java | 124 +++++++++++++++++- 7 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalSourceEntityTypeLinkRepository.java diff --git a/dspace-api/src/main/java/org/dspace/content/EntityTypeServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/EntityTypeServiceImpl.java index f3e156dd42..2790c36924 100644 --- a/dspace-api/src/main/java/org/dspace/content/EntityTypeServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/EntityTypeServiceImpl.java @@ -156,4 +156,16 @@ public class EntityTypeServiceImpl implements EntityTypeService { } return types; } + + @Override + public List getEntityTypesByNames(Context context, List names, Integer limit, Integer offset) + throws SQLException { + return entityTypeDAO.getEntityTypesByNames(context, names, limit, offset); + } + + @Override + public int countEntityTypesByNames(Context context, List names) throws SQLException { + return entityTypeDAO.countEntityTypesByNames(context, names); + } + } diff --git a/dspace-api/src/main/java/org/dspace/content/dao/EntityTypeDAO.java b/dspace-api/src/main/java/org/dspace/content/dao/EntityTypeDAO.java index 4e8a5934dd..8dbdc0ef70 100644 --- a/dspace-api/src/main/java/org/dspace/content/dao/EntityTypeDAO.java +++ b/dspace-api/src/main/java/org/dspace/content/dao/EntityTypeDAO.java @@ -8,6 +8,7 @@ package org.dspace.content.dao; import java.sql.SQLException; +import java.util.List; import org.dspace.content.EntityType; import org.dspace.core.Context; @@ -32,4 +33,25 @@ public interface EntityTypeDAO extends GenericDAO { */ public EntityType findByEntityType(Context context, String entityType) throws SQLException; + /** + * + * @param context DSpace context object + * @param names List of Entity type names that you want to retrieve + * @param limit paging limit + * @param offset the position of the first result to return + * @return + * @throws SQLException if database error + */ + public List getEntityTypesByNames(Context context, List names, Integer limit, Integer offset) + throws SQLException; + + /** + * + * @param context DSpace context object + * @param names List of Entity type names that you want to retrieve + * @return + * @throws SQLException If database error + */ + public int countEntityTypesByNames(Context context, List names) throws SQLException; + } diff --git a/dspace-api/src/main/java/org/dspace/content/dao/impl/EntityTypeDAOImpl.java b/dspace-api/src/main/java/org/dspace/content/dao/impl/EntityTypeDAOImpl.java index f7a4dcfdf3..489f4cd066 100644 --- a/dspace-api/src/main/java/org/dspace/content/dao/impl/EntityTypeDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/dao/impl/EntityTypeDAOImpl.java @@ -8,8 +8,11 @@ package org.dspace.content.dao.impl; import java.sql.SQLException; +import java.util.LinkedList; +import java.util.List; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Order; import javax.persistence.criteria.Root; import org.dspace.content.EntityType; @@ -39,4 +42,28 @@ public class EntityTypeDAOImpl extends AbstractHibernateDAO implemen entityType.toUpperCase())); return uniqueResult(context, criteriaQuery, true, EntityType.class); } + + @Override + public List getEntityTypesByNames(Context context, List names, Integer limit, Integer offset) + throws SQLException { + CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); + CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, EntityType.class); + Root entityTypeRoot = criteriaQuery.from(EntityType.class); + List orderList = new LinkedList<>(); + orderList.add(criteriaBuilder.desc(entityTypeRoot.get(EntityType_.label))); + criteriaQuery.select(entityTypeRoot).orderBy(orderList); + criteriaQuery.where(entityTypeRoot.get(EntityType_.LABEL).in(names)); + return list(context, criteriaQuery, false, EntityType.class, limit, offset); + } + + @Override + public int countEntityTypesByNames(Context context, List names) throws SQLException { + CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); + CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, EntityType.class); + Root entityTypeRoot = criteriaQuery.from(EntityType.class); + criteriaQuery.select(entityTypeRoot); + criteriaQuery.where(entityTypeRoot.get(EntityType_.LABEL).in(names)); + return count(context, criteriaQuery, criteriaBuilder, entityTypeRoot); + } + } diff --git a/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java b/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java index b06bc34c50..38b905fb74 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java @@ -61,4 +61,25 @@ public interface EntityTypeService extends DSpaceCRUDService { public List getSubmitAuthorizedTypes(Context context) throws SQLException, SolrServerException, IOException; + /** + * + * @param context DSpace context object + * @param names List of Entity type names that you want to retrieve + * @param limit paging limit + * @param offset the position of the first result to return + * @return + * @throws SQLException if database error + */ + public List getEntityTypesByNames(Context context, List names,Integer limit, Integer offset) + throws SQLException; + + /** + * + * @param context DSpace context object + * @param names List of Entity type names that you want to retrieve + * @return + * @throws SQLException if database error + */ + public int countEntityTypesByNames(Context context, List names) throws SQLException; + } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ExternalSourceRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ExternalSourceRest.java index f1f7dc7825..639c2cf72e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ExternalSourceRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ExternalSourceRest.java @@ -12,11 +12,20 @@ import org.dspace.app.rest.RestResourceController; /** * This class serves as a REST representation for an External Source */ +@LinksRest(links = { + @LinkRest( + name = ExternalSourceRest.ENTITY_TYPES, + method = "getSupportedEntityTypes" + ) +}) public class ExternalSourceRest extends BaseObjectRest { + private static final long serialVersionUID = 6951711935287912124L; + public static final String NAME = "externalsource"; public static final String PLURAL_NAME = "externalsources"; public static final String CATEGORY = RestAddressableModel.INTEGRATION; + public static final String ENTITY_TYPES = "entityTypes"; @Override public String getCategory() { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalSourceEntityTypeLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalSourceEntityTypeLinkRepository.java new file mode 100644 index 0000000000..4ed39c1893 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalSourceEntityTypeLinkRepository.java @@ -0,0 +1,73 @@ +/** + * 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; +import java.sql.SQLException; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.collections4.CollectionUtils; +import org.dspace.app.rest.model.EntityTypeRest; +import org.dspace.app.rest.model.ExternalSourceRest; +import org.dspace.app.rest.projection.Projection; +import org.dspace.app.rest.utils.ContextUtil; +import org.dspace.content.EntityType; +import org.dspace.content.service.EntityTypeService; +import org.dspace.core.Context; +import org.dspace.external.provider.AbstractExternalDataProvider; +import org.dspace.external.service.ExternalDataService; +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.stereotype.Component; + +/** + * Link repository for "EntityTypes" supported of an individual ExternalDataProvider. + * + * @author Mykhaylo Boychuk (mykhaylo.boychuk at 4science.it) + */ +@Component(ExternalSourceRest.CATEGORY + "." + ExternalSourceRest.NAME + "." + ExternalSourceRest.ENTITY_TYPES) +public class ExternalSourceEntityTypeLinkRepository extends AbstractDSpaceRestRepository + implements LinkRestRepository { + + @Autowired + private EntityTypeService entityTypeService; + + @Autowired + private ExternalDataService externalDataService; + + public Page getSupportedEntityTypes(@Nullable HttpServletRequest request, + String externalSourceName, + @Nullable Pageable pageable, + Projection projection) { + Context context = ContextUtil.obtainContext(request); + List entityTypes = Collections.emptyList(); + AbstractExternalDataProvider externalDataProvider = (AbstractExternalDataProvider) + externalDataService.getExternalDataProvider(externalSourceName); + if (Objects.isNull(externalDataProvider)) { + throw new ResourceNotFoundException("No such ExternalDataProvider: " + externalSourceName); + } + int total = 0; + List supportedEntityTypes = externalDataProvider.getSupportedEntityTypes(); + try { + if (CollectionUtils.isNotEmpty(supportedEntityTypes)) { + entityTypes = entityTypeService.getEntityTypesByNames(context, supportedEntityTypes, + Math.toIntExact(pageable.getPageSize()), + Math.toIntExact(pageable.getOffset())); + total = entityTypeService.countEntityTypesByNames(context, supportedEntityTypes); + } + } catch (SQLException e) { + throw new RuntimeException(e.getMessage(), e); + } + return converter.toRestPage(entityTypes, pageable, total, utils.obtainProjection()); + } + +} \ No newline at end of file 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 484171fcb6..1a9db10df1 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 @@ -6,20 +6,32 @@ * http://www.dspace.org/license/ */ package org.dspace.app.rest; - +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import java.util.Arrays; + +import org.dspace.app.rest.matcher.EntityTypeMatcher; import org.dspace.app.rest.matcher.ExternalSourceEntryMatcher; import org.dspace.app.rest.matcher.ExternalSourceMatcher; import org.dspace.app.rest.matcher.PageMatcher; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.dspace.builder.EntityTypeBuilder; +import org.dspace.content.EntityType; +import org.dspace.external.provider.AbstractExternalDataProvider; +import org.dspace.external.service.ExternalDataService; import org.hamcrest.Matchers; import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; public class ExternalSourcesRestControllerIT extends AbstractControllerIntegrationTest { + @Autowired + private ExternalDataService externalDataService; + @Test public void findAllExternalSources() throws Exception { getClient().perform(get("/api/integration/externalsources")) @@ -182,4 +194,114 @@ public class ExternalSourcesRestControllerIT extends AbstractControllerIntegrati .andExpect(jsonPath("$.page.totalElements", Matchers.is(4))); } + @Test + public void findSupportedEntityTypesOfAnExternalDataProviderTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + EntityType orgUnit = EntityTypeBuilder.createEntityTypeBuilder(context, "OrgUnit").build(); + EntityType project = EntityTypeBuilder.createEntityTypeBuilder(context, "Project").build(); + EntityType funding = EntityTypeBuilder.createEntityTypeBuilder(context, "Funding").build(); + + context.restoreAuthSystemState(); + + String tokenAdmin = getAuthToken(admin.getEmail(), password); + + try { + ((AbstractExternalDataProvider) externalDataService.getExternalDataProvider("mock")) + .setSupportedEntityTypes(Arrays.asList("Publication", "OrgUnit")); + ((AbstractExternalDataProvider) externalDataService.getExternalDataProvider("pubmed")) + .setSupportedEntityTypes(Arrays.asList("Project","Publication", "Funding")); + + getClient(tokenAdmin).perform(get("/api/integration/externalsources/mock/entityTypes")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.entityTypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(publication), + EntityTypeMatcher.matchEntityTypeEntry(orgUnit) + ))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(2))); + + getClient(tokenAdmin).perform(get("/api/integration/externalsources/pubmed/entityTypes")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.entityTypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(project), + EntityTypeMatcher.matchEntityTypeEntry(publication), + EntityTypeMatcher.matchEntityTypeEntry(funding) + ))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(3))); + } finally { + ((AbstractExternalDataProvider) externalDataService.getExternalDataProvider("mock")) + .setSupportedEntityTypes(null); + ((AbstractExternalDataProvider) externalDataService.getExternalDataProvider("pubmed")) + .setSupportedEntityTypes(null); + } + } + + @Test + public void findSupportedEntityTypesOfAnExternalDataProviderNotFoundTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + + context.restoreAuthSystemState(); + + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/integration/externalsources/WrongProvider/entityTypes")) + .andExpect(status().isNotFound()); + } + + @Test + public void findSupportedEntityTypesOfAnExternalDataProviderEmptyResponseTest() throws Exception { + ((AbstractExternalDataProvider) externalDataService.getExternalDataProvider("mock")) + .setSupportedEntityTypes(null); + + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/integration/externalsources/mock/entityTypes")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.entityTypes").isEmpty()) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(0))); + } + + @Test + public void findSupportedEntityTypesOfAnExternalDataProviderPaginationTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + EntityType orgUnit = EntityTypeBuilder.createEntityTypeBuilder(context, "OrgUnit").build(); + EntityType project = EntityTypeBuilder.createEntityTypeBuilder(context, "Project").build(); + + context.restoreAuthSystemState(); + + String tokenAdmin = getAuthToken(admin.getEmail(), password); + + try { + ((AbstractExternalDataProvider) externalDataService.getExternalDataProvider("mock")) + .setSupportedEntityTypes(Arrays.asList("Publication", "OrgUnit", "Project")); + + getClient(tokenAdmin).perform(get("/api/integration/externalsources/mock/entityTypes") + .param("size", "2")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.entityTypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(publication), + EntityTypeMatcher.matchEntityTypeEntry(project) + ))) + .andExpect(jsonPath("$.page.totalPages", Matchers.is(2))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(3))); + + getClient(tokenAdmin).perform(get("/api/integration/externalsources/mock/entityTypes") + .param("page", "1") + .param("size", "2")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.entityTypes", contains( + EntityTypeMatcher.matchEntityTypeEntry(orgUnit) + ))) + .andExpect(jsonPath("$.page.totalPages", Matchers.is(2))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(3))); + + } finally { + ((AbstractExternalDataProvider) externalDataService.getExternalDataProvider("mock")) + .setSupportedEntityTypes(null); + } + } + } From 84315b93a09c446e1391c91d2abde517facdfb58 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Wed, 22 Sep 2021 18:09:39 +0200 Subject: [PATCH 06/24] assigne collection entity type to item during submission proccess --- .../content/WorkspaceItemServiceImpl.java | 17 +++++++++++++++++ .../main/java/org/dspace/core/Constants.java | 6 ++++++ .../indexobject/CollectionIndexFactoryImpl.java | 11 +++++++++-- 3 files changed, 32 insertions(+), 2 deletions(-) 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 7675d298d6..cc5dcd8fd1 100644 --- a/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java @@ -12,6 +12,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import org.apache.logging.log4j.Logger; import org.dspace.app.util.DCInputsReaderException; @@ -108,6 +109,22 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService { .addPolicy(context, item, Constants.DELETE, item.getSubmitter(), ResourcePolicy.TYPE_SUBMISSION); + Optional optionalType = collection.getMetadata() + .stream() + .filter(x -> x.getMetadataField().toString('.') + .equalsIgnoreCase("dspace.entity.type")) + .findFirst(); + + if (optionalType.isPresent()) { + MetadataValue original = optionalType.get(); + MetadataField metadataField = original.getMetadataField(); + MetadataSchema metadataSchema = metadataField.getMetadataSchema(); + itemService.addMetadata(context, item, metadataSchema.getName(), metadataField.getElement(), + metadataField.getQualifier(), original.getLanguage(), original.getValue()); + } else { + itemService.addMetadata(context, item, "dspace", "entity", "type", null, Constants.UNSET_ENTITY_TYPE); + } + // Copy template if appropriate Item templateItem = collection.getTemplateItem(); diff --git a/dspace-api/src/main/java/org/dspace/core/Constants.java b/dspace-api/src/main/java/org/dspace/core/Constants.java index 6dcb7d9df2..4fae3af642 100644 --- a/dspace-api/src/main/java/org/dspace/core/Constants.java +++ b/dspace-api/src/main/java/org/dspace/core/Constants.java @@ -226,6 +226,12 @@ public class Constants { public static final String DEFAULT_ENCODING = "UTF-8"; public static final String VIRTUAL_AUTHORITY_PREFIX = "virtual::"; + + /* + * Label used by the special entity type assigned when no explicit assignment is defined + */ + public static final String UNSET_ENTITY_TYPE = "unset"; + /** * Default constructor */ diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/CollectionIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/CollectionIndexFactoryImpl.java index f1bbcb8994..57c1ffc4e5 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/CollectionIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/CollectionIndexFactoryImpl.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Optional; import java.util.UUID; +import org.apache.commons.lang3.StringUtils; import org.apache.solr.common.SolrInputDocument; import org.dspace.content.Collection; import org.dspace.content.Community; @@ -23,6 +24,7 @@ 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.core.Constants; import org.dspace.core.Context; import org.dspace.discovery.SearchUtils; import org.dspace.discovery.configuration.DiscoveryConfiguration; @@ -111,7 +113,7 @@ public class CollectionIndexFactoryImpl extends DSpaceObjectIndexFactoryImpl toIgnoreMetadataFields = SearchUtils.getIgnoredMetadataFields(collection.getType()); addContainerMetadataField(doc, highlightedMetadataFields, toIgnoreMetadataFields, "dc.description", @@ -126,7 +128,12 @@ public class CollectionIndexFactoryImpl extends DSpaceObjectIndexFactoryImpl Date: Fri, 24 Sep 2021 11:23:47 +0200 Subject: [PATCH 07/24] fix failed tests --- .../dspace/app/bulkedit/MetadataImportIT.java | 28 +++-- .../app/csv/CSVMetadataImportReferenceIT.java | 106 ++++++++++++------ .../java/org/dspace/builder/ItemBuilder.java | 4 - ...ftTiltedRelationshipMetadataServiceIT.java | 4 +- .../RelationshipMetadataServiceIT.java | 72 ++++++++---- ...htTiltedRelationshipMetadataServiceIT.java | 16 ++- .../processor/ExportEventProcessorIT.java | 35 ++++-- .../org/dspace/app/rest/PatchMetadataIT.java | 11 +- .../RelationshipDeleteRestRepositoryIT.java | 47 ++++++-- .../rest/RelationshipRestRepositoryIT.java | 86 ++++++-------- .../RelationshipTypeRestControllerIT.java | 26 ++--- .../rest/WorkspaceItemRestRepositoryIT.java | 6 +- .../org/dspace/app/rest/csv/CsvExportIT.java | 8 +- .../org/dspace/app/rest/csv/CsvImportIT.java | 22 ++-- 14 files changed, 286 insertions(+), 185 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataImportIT.java b/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataImportIT.java index 2b30ea8cd3..15a2865e8f 100644 --- a/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataImportIT.java +++ b/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataImportIT.java @@ -52,7 +52,8 @@ public class MetadataImportIT extends AbstractIntegrationTestWithDatabase { private EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); private RelationshipService relationshipService = ContentServiceFactory.getInstance().getRelationshipService(); - Collection collection; + private Collection publicationCollection; + private Collection personCollection; @Before @Override @@ -60,14 +61,19 @@ public class MetadataImportIT extends AbstractIntegrationTestWithDatabase { super.setUp(); context.turnOffAuthorisationSystem(); Community community = CommunityBuilder.createCommunity(context).build(); - this.collection = CollectionBuilder.createCollection(context, community).build(); + this.publicationCollection = CollectionBuilder.createCollection(context, community) + .withEntityType("Publication") + .build(); + this.personCollection = CollectionBuilder.createCollection(context, community) + .withEntityType("Person") + .build(); context.restoreAuthSystemState(); } @Test public void metadataImportTest() throws Exception { String[] csv = {"id,collection,dc.title,dc.contributor.author", - "+," + collection.getHandle() + ",\"Test Import 1\"," + "\"Donald, SmithImported\""}; + "+," + publicationCollection.getHandle() + ",\"Test Import 1\"," + "\"Donald, SmithImported\""}; performImportScript(csv); Item importedItem = findItemByName("Test Import 1"); assertTrue( @@ -105,7 +111,7 @@ public class MetadataImportIT extends AbstractIntegrationTestWithDatabase { @Test public void relationshipMetadataImportTest() throws Exception { context.turnOffAuthorisationSystem(); - Item item = ItemBuilder.createItem(context, collection).withEntityType("Publication") + Item item = ItemBuilder.createItem(context, publicationCollection) .withTitle("Publication1").build(); EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); EntityType person = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); @@ -114,7 +120,7 @@ public class MetadataImportIT extends AbstractIntegrationTestWithDatabase { context.restoreAuthSystemState(); String[] csv = {"id,collection,dc.title,relation.isPublicationOfAuthor,dspace.entity.type", - "+," + collection.getHandle() + ",\"Test Import 1\"," + item.getID() + ",Person"}; + "+," + personCollection.getHandle() + ",\"Test Import 1\"," + item.getID() + ",Person"}; performImportScript(csv); Item importedItem = findItemByName("Test Import 1"); @@ -128,11 +134,11 @@ public class MetadataImportIT extends AbstractIntegrationTestWithDatabase { @Test public void relationshipMetadataImporAlreadyExistingItemTest() throws Exception { context.turnOffAuthorisationSystem(); - Item personItem = ItemBuilder.createItem(context, collection).withEntityType("Person") + Item personItem = ItemBuilder.createItem(context, personCollection) .withTitle("Person1").build(); List relationshipList = relationshipService.findByItem(context, personItem); assertEquals(0, relationshipList.size()); - Item publicationItem = ItemBuilder.createItem(context, collection).withEntityType("Publication") + Item publicationItem = ItemBuilder.createItem(context, publicationCollection) .withTitle("Publication1").build(); EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); @@ -143,7 +149,7 @@ public class MetadataImportIT extends AbstractIntegrationTestWithDatabase { String[] csv = {"id,collection,relation.isPublicationOfAuthor", - personItem.getID() + "," + collection.getHandle() + "," + publicationItem.getID()}; + personItem.getID() + "," + publicationCollection.getHandle() + "," + publicationItem.getID()}; performImportScript(csv); Item importedItem = findItemByName("Person1"); @@ -156,7 +162,7 @@ public class MetadataImportIT extends AbstractIntegrationTestWithDatabase { public void personMetadataImportTest() throws Exception { String[] csv = {"id,collection,dc.title,person.birthDate", - "+," + collection.getHandle() + ",\"Test Import 2\"," + "2000"}; + "+," + publicationCollection.getHandle() + ",\"Test Import 2\"," + "2000"}; performImportScript(csv); Item importedItem = findItemByName("Test Import 2"); assertTrue( @@ -172,7 +178,7 @@ public class MetadataImportIT extends AbstractIntegrationTestWithDatabase { public void metadataImportRemovingValueTest() throws Exception { context.turnOffAuthorisationSystem(); - Item item = ItemBuilder.createItem(context, collection).withAuthor("TestAuthorToRemove").withTitle("title") + Item item = ItemBuilder.createItem(context,personCollection).withAuthor("TestAuthorToRemove").withTitle("title") .build(); context.restoreAuthSystemState(); @@ -182,7 +188,7 @@ public class MetadataImportIT extends AbstractIntegrationTestWithDatabase { "TestAuthorToRemove")); String[] csv = {"id,collection,dc.title,dc.contributor.author[*]", - item.getID().toString() + "," + collection.getHandle() + "," + item.getName() + ","}; + item.getID().toString() + "," + personCollection.getHandle() + "," + item.getName() + ","}; performImportScript(csv); item = findItemByName("title"); assertEquals(itemService.getMetadata(item, "dc", "contributor", "author", Item.ANY).size(), 0); diff --git a/dspace-api/src/test/java/org/dspace/app/csv/CSVMetadataImportReferenceIT.java b/dspace-api/src/test/java/org/dspace/app/csv/CSVMetadataImportReferenceIT.java index 34b075b6e7..c5a10d6f59 100644 --- a/dspace-api/src/test/java/org/dspace/app/csv/CSVMetadataImportReferenceIT.java +++ b/dspace-api/src/test/java/org/dspace/app/csv/CSVMetadataImportReferenceIT.java @@ -55,6 +55,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat //Common collection to utilize for test private Collection col1; + private Collection col2; private RelationshipService relationshipService = ContentServiceFactory.getInstance().getRelationshipService(); private ItemService itemService = ContentServiceFactory.getInstance().getItemService(); @@ -72,8 +73,15 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withName("Parent Community") .build(); - col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType("Person") + .withName("Collection 1") + .build(); + col2 = CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType("Publication") + .withName("Collection 1") + .build(); context.turnOffAuthorisationSystem(); @@ -130,7 +138,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat public void testSingleMdRef() throws Exception { String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other", "+,Person,," + col1.getHandle() + ",0", - "+,Publication,dc.identifier.other:0," + col1.getHandle() + ",1"}; + "+,Publication,dc.identifier.other:0," + col2.getHandle() + ",1"}; Item[] items = runImport(csv); assertRelationship(items[1], items[0], 1, "left", 0); } @@ -160,7 +168,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat String[] csv = {"id,dc.title,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName," + "dc.identifier.other", "+,Test Item 1,Person,," + col1.getHandle() + ",idVal,0", - "+,Test Item 2,Publication,rowName:idVal," + col1.getHandle() + ",anything,1"}; + "+,Test Item 2,Publication,rowName:idVal," + col2.getHandle() + ",anything,1"}; Item[] items = runImport(csv); assertRelationship(items[1], items[0], 1, "left", 0); } @@ -174,7 +182,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other", "+,Person,," + col1.getHandle() + ",0", "+,Person,," + col1.getHandle() + ",1", - "+,Publication,dc.identifier.other:0||dc.identifier.other:1," + col1.getHandle() + ",2"}; + "+,Publication,dc.identifier.other:0||dc.identifier.other:1," + col2.getHandle() + ",2"}; Item[] items = runImport(csv); assertRelationship(items[2], items[0], 1, "left", 0); assertRelationship(items[2], items[1], 1, "left", 1); @@ -189,7 +197,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other,rowName", "+,Person,," + col1.getHandle() + ",0,val1", "+,Person,," + col1.getHandle() + ",1,val2", - "+,Publication,rowName:val1||rowName:val2," + col1.getHandle() + ",2,val3"}; + "+,Publication,rowName:val1||rowName:val2," + col2.getHandle() + ",2,val3"}; Item[] items = runImport(csv); assertRelationship(items[2], items[0], 1, "left", 0); assertRelationship(items[2], items[1], 1, "left", 1); @@ -208,11 +216,10 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .build(); context.restoreAuthSystemState(); String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName,dc.identifier.other", - "+,Publication," + person.getID().toString() + "," + col1.getHandle() + ",anything,0"}; + "+,Publication," + person.getID().toString() + "," + col2.getHandle() + ",anything,0"}; Item[] items = runImport(csv); assertRelationship(items[0], person, 1, "left", 0); } @@ -230,7 +237,6 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .build(); Item person2 = ItemBuilder.createItem(context, col1) .withTitle("Author2") @@ -238,11 +244,10 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, John") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("John") - .withEntityType("Person") .build(); String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName,dc.identifier.other", "+,Publication," + person.getID().toString() + "||" + person2.getID().toString() + "," + - col1.getHandle() + ",anything,0"}; + col2.getHandle() + ",anything,0"}; Item[] items = runImport(csv); assertRelationship(items[0], person, 1, "left", 0); assertRelationship(items[0], person2, 1, "left", 1); @@ -261,12 +266,11 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .build(); String[] csv = {"id,dc.title,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName," + "dc.identifier.other", "+,Person2,Person,," + col1.getHandle() + ",idVal,0", - "+,Pub1,Publication,dc.title:Person||dc.title:Person2," + col1.getHandle() + ",anything,1"}; + "+,Pub1,Publication,dc.title:Person||dc.title:Person2," + col2.getHandle() + ",anything,1"}; context.restoreAuthSystemState(); Item[] items = runImport(csv); assertRelationship(items[1], person, 1, "left", 0); @@ -287,7 +291,6 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .build(); Item person2 = ItemBuilder.createItem(context, col1) .withTitle("Person2") @@ -295,7 +298,6 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, John") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("John") - .withEntityType("Person") .build(); context.restoreAuthSystemState(); @@ -303,7 +305,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat "dc.identifier.other", "+,Person3,Person,," + col1.getHandle() + ",idVal,0", "+,Pub1,Publication," + person.getID() + "||dc.title:Person2||rowName:idVal," + - col1.getHandle() + ",anything,1"}; + col2.getHandle() + ",anything,1"}; Item[] items = runImport(csv); assertRelationship(items[1], person, 1, "left", 0); assertRelationship(items[1], person2, 1, "left", 1); @@ -319,7 +321,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat String[] csv = {"id,dc.title,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName," + "dc.identifier.other", "+,Person:,Person,," + col1.getHandle() + ",idVal,0", - "+,Pub1,Publication,dc.title:Person:," + col1.getHandle() + ",anything,1"}; + "+,Pub1,Publication,dc.title:Person:," + col2.getHandle() + ",anything,1"}; Item[] items = runImport(csv); assertRelationship(items[1], items[0], 1, "left", 0); } @@ -360,7 +362,6 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .withIdentifierOther("1") .build(); Item person2 = ItemBuilder.createItem(context, col1) @@ -369,7 +370,6 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, John") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("John") - .withEntityType("Person") .withIdentifierOther("1") .build(); @@ -391,7 +391,6 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .withIdentifierOther("1") .build(); context.restoreAuthSystemState(); @@ -451,11 +450,21 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat @Test(expected = MetadataImportInvalidHeadingException.class) public void testInvalidRelationshipArchivedOrigin() throws Exception { context.turnOffAuthorisationSystem(); - Item testItem = ItemBuilder.createItem(context, col1) + + Community rootCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Collection orgUnitCollection = CollectionBuilder.createCollection(context, rootCommunity) + .withEntityType("OrgUnit") + .withName("Collection 1") + .build(); + + Item testItem = ItemBuilder.createItem(context, orgUnitCollection) .withTitle("OrgUnit") .withIssueDate("2017-10-17") - .withEntityType("OrgUnit") .build(); + context.restoreAuthSystemState(); String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName", "+,Person,," + col1.getHandle() + ",1" + @@ -469,11 +478,21 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat @Test(expected = MetadataImportInvalidHeadingException.class) public void testInvalidRelationshipArchivedTarget() throws Exception { context.turnOffAuthorisationSystem(); - Item testItem = ItemBuilder.createItem(context, col1) + + Community rootCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Collection orgUnitCollection = CollectionBuilder.createCollection(context, rootCommunity) + .withEntityType("OrgUnit") + .withName("Collection 1") + .build(); + + Item testItem = ItemBuilder.createItem(context, orgUnitCollection) .withTitle("OrgUnit") .withIssueDate("2017-10-17") - .withEntityType("OrgUnit") .build(); + context.restoreAuthSystemState(); String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName", testItem.getID().toString() + ",Person,," + col1.getHandle() + ",1" + @@ -488,29 +507,40 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat public void testValidRelationshipNoDefinedTypesInCSV() throws Exception { context.turnOffAuthorisationSystem(); + Community rootCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Collection publicationCollection = CollectionBuilder.createCollection(context, rootCommunity) + .withEntityType("Publication") + .withName("Collection 1") + .build(); + + Collection projectCollection = CollectionBuilder.createCollection(context, rootCommunity) + .withEntityType("Project") + .withName("Collection 1") + .build(); + Item testItem = ItemBuilder.createItem(context, col1) .withTitle("Person") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .withIdentifierOther("testItemOne") .build(); - Item testItem2 = ItemBuilder.createItem(context, col1) + Item testItem2 = ItemBuilder.createItem(context, publicationCollection) .withTitle("Publication") .withIssueDate("2017-10-17") - .withEntityType("Publication") .withIdentifierOther("testItemTwo") .build(); - Item testItem3 = ItemBuilder.createItem(context, col1) + Item testItem3 = ItemBuilder.createItem(context, projectCollection) .withTitle("Project") .withIssueDate("2017-10-17") - .withEntityType("Project") .withIdentifierOther("testItemThree") .build(); @@ -532,8 +562,8 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat public void testDuplicateRowNameReferences() throws Exception { String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other,rowName", "+,Person,," + col1.getHandle() + ",0,value", - "+,Publication,rowName:value," + col1.getHandle() + ",1,1", - "+,Publication,rowName:value," + col1.getHandle() + ",2,2"}; + "+,Publication,rowName:value," + col2.getHandle() + ",1,1", + "+,Publication,rowName:value," + col2.getHandle() + ",2,2"}; Item[] items = runImport(csv); assertRelationship(items[1], items[0], 1, "left", 0); assertRelationship(items[2], items[0], 1, "left", 0); @@ -548,13 +578,12 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .withIdentifierOther("testItemOne") .build(); String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other,rowName", - "+,Publication," + testItem.getID() + "::virtual::4::600," + col1.getHandle() + ",0,1"}; + "+,Publication," + testItem.getID() + "::virtual::4::600," + col2.getHandle() + ",0,1"}; Item[] items = runImport(csv); assertRelationship(items[0], testItem, 1, "left", 0); } @@ -566,11 +595,20 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat public void testInvalidTypeNameDefined() throws Exception { context.turnOffAuthorisationSystem(); - Item testItem = ItemBuilder.createItem(context, col1) + Community rootCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Collection publicationCollection = CollectionBuilder.createCollection(context, rootCommunity) + .withEntityType("Publication") + .withName("Collection 1") + .build(); + + Item testItem = ItemBuilder.createItem(context, publicationCollection) .withTitle("Publication") .withIssueDate("2017-10-17") - .withEntityType("Publication") .build(); + context.restoreAuthSystemState(); String[] csv = {"id,collection,dspace.entity.type,dc.title," + "relation.isProjectOfPublication,relation.isPublicationOfProject", 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 c4bdbe7d54..141322fdf5 100644 --- a/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java @@ -95,10 +95,6 @@ public class ItemBuilder extends AbstractDSpaceObjectBuilder { subject, authority, confidence); } - public ItemBuilder withEntityType(final String entityType) { - return addMetadataValue(item, "dspace", "entity", "type", entityType); - } - public ItemBuilder withType(final String type) { return addMetadataValue(item, "dc", "type", null, type); } diff --git a/dspace-api/src/test/java/org/dspace/content/LeftTiltedRelationshipMetadataServiceIT.java b/dspace-api/src/test/java/org/dspace/content/LeftTiltedRelationshipMetadataServiceIT.java index f8b836ca51..4aa0677bc5 100644 --- a/dspace-api/src/test/java/org/dspace/content/LeftTiltedRelationshipMetadataServiceIT.java +++ b/dspace-api/src/test/java/org/dspace/content/LeftTiltedRelationshipMetadataServiceIT.java @@ -33,8 +33,8 @@ public class LeftTiltedRelationshipMetadataServiceIT extends RelationshipMetadat EntityType publicationEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); EntityType authorEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "Author").build(); - leftItem = ItemBuilder.createItem(context, col).withEntityType("Publication").build(); - rightItem = ItemBuilder.createItem(context, col).withEntityType("Author") + leftItem = ItemBuilder.createItem(context, col).build(); + rightItem = ItemBuilder.createItem(context, col2) .withPersonIdentifierLastName("familyName") .withPersonIdentifierFirstName("firstName").build(); isAuthorOfPublicationRelationshipType = 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 8ade8ca1f6..a1996a64fc 100644 --- a/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java +++ b/dspace-api/src/test/java/org/dspace/content/RelationshipMetadataServiceIT.java @@ -56,6 +56,7 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa Item leftItem; Item rightItem; Collection col; + Collection col2; Relationship relationship; RelationshipType isAuthorOfPublicationRelationshipType; @@ -75,10 +76,15 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa context.turnOffAuthorisationSystem(); Community community = CommunityBuilder.createCommunity(context).build(); - col = CollectionBuilder.createCollection(context, community).build(); + col = CollectionBuilder.createCollection(context, community) + .withEntityType("Publication") + .build(); + col2 = CollectionBuilder.createCollection(context, community) + .withEntityType("Author") + .build(); leftItem = ItemBuilder.createItem(context, col).build(); - rightItem = ItemBuilder.createItem(context, col).build(); + rightItem = ItemBuilder.createItem(context, col2).build(); context.restoreAuthSystemState(); } @@ -90,8 +96,8 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa context.turnOffAuthorisationSystem(); EntityType publicationEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); EntityType authorEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "Author").build(); - leftItem = ItemBuilder.createItem(context, col).withEntityType("Publication").build(); - rightItem = ItemBuilder.createItem(context, col).withEntityType("Author") + leftItem = ItemBuilder.createItem(context, col).build(); + rightItem = ItemBuilder.createItem(context, col2) .withPersonIdentifierLastName("familyName") .withPersonIdentifierFirstName("firstName").build(); isAuthorOfPublicationRelationshipType = @@ -114,8 +120,8 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa context.turnOffAuthorisationSystem(); EntityType publicationEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); EntityType authorEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "Author").build(); - leftItem = ItemBuilder.createItem(context, col).withEntityType("Publication").build(); - rightItem = ItemBuilder.createItem(context, col).withEntityType("Author") + leftItem = ItemBuilder.createItem(context, col).build(); + rightItem = ItemBuilder.createItem(context, col2) .withPersonIdentifierLastName("familyName") .withPersonIdentifierFirstName("firstName").build(); RelationshipType isAuthorOfPublication = @@ -135,12 +141,21 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa */ protected void initJournalVolumeIssue() throws Exception { context.turnOffAuthorisationSystem(); + Community community = CommunityBuilder.createCommunity(context).build(); + + Collection col = CollectionBuilder.createCollection(context, community) + .withEntityType("JournalIssue") + .build(); + Collection col2 = CollectionBuilder.createCollection(context, community) + .withEntityType("JournalVolume") + .build(); + EntityType journalIssueEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "JournalIssue").build(); EntityType publicationVolumeEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "JournalVolume").build(); - leftItem = ItemBuilder.createItem(context, col).withEntityType("JournalIssue") + leftItem = ItemBuilder.createItem(context, col) .withPublicationIssueNumber("2").build(); - rightItem = ItemBuilder.createItem(context, col).withEntityType("JournalVolume") + rightItem = ItemBuilder.createItem(context, col2) .withPublicationVolumeNumber("30").build(); RelationshipType isIssueOfVolume = RelationshipTypeBuilder @@ -607,10 +622,8 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa assertThat(relationshipService.findNextRightPlaceByRightItem(context, rightItem), equalTo(1)); context.turnOffAuthorisationSystem(); - Community community = CommunityBuilder.createCommunity(context).build(); - Collection col = CollectionBuilder.createCollection(context, community).build(); - Item secondItem = ItemBuilder.createItem(context, col).withEntityType("Publication").build(); + Item secondItem = ItemBuilder.createItem(context, col).build(); RelationshipBuilder.createRelationshipBuilder(context, secondItem, rightItem, isAuthorOfPublicationRelationshipType).build(); context.restoreAuthSystemState(); @@ -626,10 +639,8 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa assertThat(relationshipService.findNextLeftPlaceByLeftItem(context, leftItem), equalTo(1)); context.turnOffAuthorisationSystem(); - Community community = CommunityBuilder.createCommunity(context).build(); - Collection col = CollectionBuilder.createCollection(context, community).build(); - Item secondAuthor = ItemBuilder.createItem(context, col).withEntityType("Author") + Item secondAuthor = ItemBuilder.createItem(context, col2) .withPersonIdentifierFirstName("firstName") .withPersonIdentifierLastName("familyName").build(); @@ -647,6 +658,22 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa // Journal, JournalVolume, JournalIssue, Publication items, related to each other using the relationship types // isJournalOfVolume, isJournalVolumeOfIssue, isJournalIssueOfPublication. context.turnOffAuthorisationSystem(); + + Community community = CommunityBuilder.createCommunity(context).build(); + + Collection col = CollectionBuilder.createCollection(context, community) + .withEntityType("JournalIssue") + .build(); + Collection col2 = CollectionBuilder.createCollection(context, community) + .withEntityType("JournalVolume") + .build(); + Collection col3 = CollectionBuilder.createCollection(context, community) + .withEntityType("Journal") + .build(); + Collection col4 = CollectionBuilder.createCollection(context, community) + .withEntityType("Publication") + .build(); + EntityType publicationEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); EntityType journalIssueEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "JournalIssue").build(); EntityType journalVolumeEntityType = @@ -666,24 +693,21 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa null) .build(); - Community community = CommunityBuilder.createCommunity(context).build(); - Collection collection = CollectionBuilder.createCollection(context, community).build(); - - Item journalIssue = ItemBuilder.createItem(context, collection).withEntityType("JournalIssue").build(); - Item journalVolume = ItemBuilder.createItem(context, collection) + Item journalIssue = ItemBuilder.createItem(context, col).build(); + Item journalVolume = ItemBuilder.createItem(context, col2) .withPublicationVolumeNumber("30") - .withEntityType("JournalVolume").build(); - Item journal = ItemBuilder.createItem(context, collection) + .build(); + Item journal = ItemBuilder.createItem(context, col3) .withMetadata("creativeworkseries", "issn", null, "issn journal") - .withEntityType("Journal").build(); + .build(); RelationshipBuilder.createRelationshipBuilder(context, journalIssue, journalVolume, isJournalVolumeOfIssueRelationshipType).build(); RelationshipBuilder.createRelationshipBuilder(context, journalVolume, journal, isJournalVolumeOfJournalRelationshipType).build(); - Item publication = ItemBuilder.createItem(context, collection) + Item publication = ItemBuilder.createItem(context, col4) .withTitle("Pub 1") - .withEntityType("Publication").build(); + .build(); RelationshipBuilder.createRelationshipBuilder(context, publication, journalIssue, isJournalIssueOfPublicationRelationshipType).build(); diff --git a/dspace-api/src/test/java/org/dspace/content/RightTiltedRelationshipMetadataServiceIT.java b/dspace-api/src/test/java/org/dspace/content/RightTiltedRelationshipMetadataServiceIT.java index 92d2961a43..fc57f588db 100644 --- a/dspace-api/src/test/java/org/dspace/content/RightTiltedRelationshipMetadataServiceIT.java +++ b/dspace-api/src/test/java/org/dspace/content/RightTiltedRelationshipMetadataServiceIT.java @@ -12,6 +12,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import java.util.List; +import org.dspace.builder.CollectionBuilder; +import org.dspace.builder.CommunityBuilder; import org.dspace.builder.EntityTypeBuilder; import org.dspace.builder.ItemBuilder; import org.dspace.builder.RelationshipBuilder; @@ -29,12 +31,22 @@ public class RightTiltedRelationshipMetadataServiceIT extends RelationshipMetada @Override protected void initJournalVolumeIssue() throws Exception { context.turnOffAuthorisationSystem(); + + Community community = CommunityBuilder.createCommunity(context).build(); + + Collection col = CollectionBuilder.createCollection(context, community) + .withEntityType("JournalIssue") + .build(); + Collection col2 = CollectionBuilder.createCollection(context, community) + .withEntityType("JournalVolume") + .build(); + EntityType journalIssueEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "JournalIssue").build(); EntityType publicationVolumeEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "JournalVolume").build(); - leftItem = ItemBuilder.createItem(context, col).withEntityType("JournalIssue") + leftItem = ItemBuilder.createItem(context, col) .withPublicationIssueNumber("2").build(); - rightItem = ItemBuilder.createItem(context, col).withEntityType("JournalVolume") + rightItem = ItemBuilder.createItem(context, col2) .withPublicationVolumeNumber("30").build(); RelationshipType isIssueOfVolume = RelationshipTypeBuilder diff --git a/dspace-api/src/test/java/org/dspace/statistics/export/processor/ExportEventProcessorIT.java b/dspace-api/src/test/java/org/dspace/statistics/export/processor/ExportEventProcessorIT.java index 44848d579b..e42003e4fc 100644 --- a/dspace-api/src/test/java/org/dspace/statistics/export/processor/ExportEventProcessorIT.java +++ b/dspace-api/src/test/java/org/dspace/statistics/export/processor/ExportEventProcessorIT.java @@ -134,8 +134,10 @@ public class ExportEventProcessorIT extends AbstractIntegrationTestWithDatabase public void testShouldProcessItemWhenCanEdit() throws SQLException { context.turnOffAuthorisationSystem(); Community community = CommunityBuilder.createCommunity(context).build(); - Collection collection = CollectionBuilder.createCollection(context, community).build(); - Item item = ItemBuilder.createItem(context, collection).withEntityType(otherEntity.getLabel()).build(); + Collection collection = CollectionBuilder.createCollection(context, community) + .withEntityType(otherEntity.getLabel()) + .build(); + Item item = ItemBuilder.createItem(context, collection).build(); context.restoreAuthSystemState(); context.setCurrentUser(admin); @@ -154,10 +156,11 @@ public class ExportEventProcessorIT extends AbstractIntegrationTestWithDatabase context.turnOffAuthorisationSystem(); Community community = CommunityBuilder.createCommunity(context).build(); - Collection collection = CollectionBuilder.createCollection(context, community).build(); + Collection collection = CollectionBuilder.createCollection(context, community) + .withEntityType(publication.getLabel()) + .build(); Item item = ItemBuilder.createItem(context, collection) .withType("Excluded type") - .withEntityType(publication.getLabel()) .build(); context.restoreAuthSystemState(); @@ -176,8 +179,10 @@ public class ExportEventProcessorIT extends AbstractIntegrationTestWithDatabase public void testShouldProcessItemWhenShouldNotProcessEntity() throws SQLException { context.turnOffAuthorisationSystem(); Community community = CommunityBuilder.createCommunity(context).build(); - Collection collection = CollectionBuilder.createCollection(context, community).build(); - Item item = ItemBuilder.createItem(context, collection).withEntityType(otherEntity.getLabel()).build(); + Collection collection = CollectionBuilder.createCollection(context, community) + .withEntityType(otherEntity.getLabel()) + .build(); + Item item = ItemBuilder.createItem(context, collection).build(); context.restoreAuthSystemState(); ExportEventProcessor exportEventProcessor = new ItemEventProcessor(context, request, item); @@ -194,8 +199,10 @@ public class ExportEventProcessorIT extends AbstractIntegrationTestWithDatabase public void testShouldProcessItem() throws SQLException { context.turnOffAuthorisationSystem(); Community community = CommunityBuilder.createCommunity(context).build(); - Collection collection = CollectionBuilder.createCollection(context, community).build(); - Item item = ItemBuilder.createItem(context, collection).withEntityType(publication.getLabel()).build(); + Collection collection = CollectionBuilder.createCollection(context, community) + .withEntityType(publication.getLabel()) + .build(); + Item item = ItemBuilder.createItem(context, collection).build(); context.restoreAuthSystemState(); ExportEventProcessor exportEventProcessor = new ItemEventProcessor(context, request, item); @@ -213,8 +220,10 @@ public class ExportEventProcessorIT extends AbstractIntegrationTestWithDatabase public void testShouldProcessEntityType() throws SQLException { context.turnOffAuthorisationSystem(); Community community = CommunityBuilder.createCommunity(context).build(); - Collection collection = CollectionBuilder.createCollection(context, community).build(); - Item item = ItemBuilder.createItem(context, collection).withEntityType(publication.getLabel()).build(); + Collection collection = CollectionBuilder.createCollection(context, community) + .withEntityType(publication.getLabel()) + .build(); + Item item = ItemBuilder.createItem(context, collection).build(); context.restoreAuthSystemState(); ExportEventProcessor exportEventProcessor = new ItemEventProcessor(context, request, item); @@ -231,8 +240,10 @@ public class ExportEventProcessorIT extends AbstractIntegrationTestWithDatabase public void testShouldProcessEntityTypeWhenNotInList() throws SQLException { context.turnOffAuthorisationSystem(); Community community = CommunityBuilder.createCommunity(context).build(); - Collection collection = CollectionBuilder.createCollection(context, community).build(); - Item item = ItemBuilder.createItem(context, collection).withEntityType(otherEntity.getLabel()).build(); + Collection collection = CollectionBuilder.createCollection(context, community) + .withEntityType(otherEntity.getLabel()) + .build(); + Item item = ItemBuilder.createItem(context, collection).build(); context.restoreAuthSystemState(); ExportEventProcessor exportEventProcessor = new ItemEventProcessor(context, request, item); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/PatchMetadataIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/PatchMetadataIT.java index 7c57e98f1c..b1134e5376 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/PatchMetadataIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/PatchMetadataIT.java @@ -76,6 +76,7 @@ public class PatchMetadataIT extends AbstractEntityIntegrationTest { private WorkspaceItemService workspaceItemService; private Collection collection; + private Collection collection2; private WorkspaceItem publicationItem; private Item personItem1; private Item personItem2; @@ -102,6 +103,11 @@ public class PatchMetadataIT extends AbstractEntityIntegrationTest { .build(); collection = CollectionBuilder.createCollection(context, community) .withName("Collection") + .withEntityType("Person") + .build(); + collection2 = CollectionBuilder.createCollection(context, community) + .withName("Collection") + .withEntityType("Publication") .build(); context.restoreAuthSystemState(); @@ -143,17 +149,14 @@ public class PatchMetadataIT extends AbstractEntityIntegrationTest { .withTitle("Person 1") .withPersonIdentifierFirstName("Sarah") .withPersonIdentifierLastName("Dahlen") - .withEntityType("Person") .build(); personItem2 = ItemBuilder.createItem(context, collection) .withTitle("Person 2") .withPersonIdentifierFirstName("Oliver") .withPersonIdentifierLastName("Linton") - .withEntityType("Person") .build(); - publicationItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection) + publicationItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection2) .withTitle("Publication 1") - .withEntityType("Publication") .build(); publicationPersonRelationshipType = relationshipTypeService.findbyTypesAndTypeName(context, entityTypeService.findByEntityType(context, "Publication"), 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 d28e649dbf..7df0b40068 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 @@ -60,6 +60,10 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio private Item leftItem; private Item rightItem; private Collection collection; + private Collection collection2; + private Collection collection3; + private Collection collection4; + private Collection collection5; private RelationshipType relationshipType; private Relationship relationship; private String adminAuthToken; @@ -98,7 +102,33 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio collection = CollectionBuilder.createCollection(context, community) .withName("Collection") .withAdminGroup(collectionAdmin) + .withEntityType("Publication") .build(); + + collection2 = CollectionBuilder.createCollection(context, community) + .withName("Collection 2") + .withAdminGroup(collectionAdmin) + .withEntityType("Person") + .build(); + + collection3 = CollectionBuilder.createCollection(context, community) + .withName("Collection 3") + .withAdminGroup(collectionAdmin) + .withEntityType("JournalIssue") + .build(); + + collection4 = CollectionBuilder.createCollection(context, community) + .withName("Collection 4") + .withAdminGroup(collectionAdmin) + .withEntityType("JournalVolume") + .build(); + + collection5 = CollectionBuilder.createCollection(context, community) + .withName("Collection 4") + .withAdminGroup(collectionAdmin) + .withEntityType("Project") + .build(); + context.restoreAuthSystemState(); } @@ -122,11 +152,9 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio leftItem = ItemBuilder.createItem(context, collection) .withTitle("Left item") - .withEntityType("Publication") .build(); - rightItem = ItemBuilder.createItem(context, collection) + rightItem = ItemBuilder.createItem(context, collection2) .withTitle("Right item") - .withEntityType("Person") .withPersonIdentifierFirstName("firstName") .withPersonIdentifierLastName("familyName") .build(); @@ -144,14 +172,12 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio private void initJournalVolumeIssue() throws Exception { context.turnOffAuthorisationSystem(); - leftItem = ItemBuilder.createItem(context, collection) + leftItem = ItemBuilder.createItem(context, collection3) .withTitle("Left item") - .withEntityType("JournalIssue") .withPublicationIssueNumber("2") .build(); - rightItem = ItemBuilder.createItem(context, collection) + rightItem = ItemBuilder.createItem(context, collection4) .withTitle("Right item") - .withEntityType("JournalVolume") .withPublicationVolumeNumber("30") .build(); relationshipType = relationshipTypeService @@ -167,19 +193,16 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio private void initPersonProjectPublication() throws Exception { context.turnOffAuthorisationSystem(); - personItem = ItemBuilder.createItem(context, collection) + personItem = ItemBuilder.createItem(context, collection2) .withTitle("Person 1") .withPersonIdentifierFirstName("Donald") .withPersonIdentifierLastName("Smith") - .withEntityType("Person") .build(); - projectItem = ItemBuilder.createItem(context, collection) + projectItem = ItemBuilder.createItem(context, collection5) .withTitle("Project 1") - .withEntityType("Project") .build(); publicationItem = ItemBuilder.createItem(context, collection) .withTitle("Publication 1") - .withEntityType("Publication") .build(); personProjectRelationshipType = relationshipTypeService.findbyTypesAndTypeName(context, entityTypeService.findByEntityType(context, "Person"), 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 b64a5c95a8..0a094e9258 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 @@ -104,6 +104,10 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest protected Collection col1; protected Collection col2; protected Collection col3; + protected Collection col4; + protected Collection col5; + protected Collection col6; + protected Collection col7; protected Item author1; protected Item author2; @@ -134,9 +138,20 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest .withName("Sub Community") .build(); - col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build(); - col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build(); - col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build(); + col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1") + .withEntityType("Person").build(); + col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2") + .withEntityType("Publication").build(); + col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits") + .withEntityType("OrgUnit").build(); + col4 = CollectionBuilder.createCollection(context, child1).withName("Projects") + .withEntityType("Project").build(); + col5 = CollectionBuilder.createCollection(context, child1).withName("Projects") + .withEntityType("Journal").build(); + col6 = CollectionBuilder.createCollection(context, child1).withName("Projects") + .withEntityType("JournalVolume").build(); + col7 = CollectionBuilder.createCollection(context, child1).withName("Projects") + .withEntityType("JournalIssue").build(); author1 = ItemBuilder.createItem(context, col1) .withTitle("Author1") @@ -144,64 +159,55 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .build(); - author2 = ItemBuilder.createItem(context, col2) + author2 = ItemBuilder.createItem(context, col1) .withTitle("Author2") .withIssueDate("2016-02-13") .withAuthor("Smith, Maria") - .withEntityType("Person") .build(); - author3 = ItemBuilder.createItem(context, col2) + author3 = ItemBuilder.createItem(context, col1) .withTitle("Author3") .withIssueDate("2016-02-13") .withPersonIdentifierFirstName("Maybe") .withPersonIdentifierLastName("Maybe") - .withEntityType("Person") .build(); - publication1 = ItemBuilder.createItem(context, col3) + publication1 = ItemBuilder.createItem(context, col2) .withTitle("Publication1") .withAuthor("Testy, TEst") .withIssueDate("2015-01-01") - .withEntityType("Publication") .build(); - publication2 = ItemBuilder.createItem(context, col3) + publication2 = ItemBuilder.createItem(context, col2) .withTitle("Publication2") .withAuthor("Testy, TEst") .withIssueDate("2015-01-01") - .withEntityType("Publication") .build(); orgUnit1 = ItemBuilder.createItem(context, col3) .withTitle("OrgUnit1") .withAuthor("Testy, TEst") .withIssueDate("2015-01-01") - .withEntityType("OrgUnit") .build(); orgUnit2 = ItemBuilder.createItem(context, col3) .withTitle("OrgUnit2") .withAuthor("Testy, TEst") .withIssueDate("2015-01-01") - .withEntityType("OrgUnit") .build(); orgUnit3 = ItemBuilder.createItem(context, col3) .withTitle("OrgUnit3") .withAuthor("Test, Testy") .withIssueDate("2015-02-01") - .withEntityType("OrgUnit") .build(); - project1 = ItemBuilder.createItem(context, col3) + project1 = ItemBuilder.createItem(context, col4) .withTitle("Project1") .withAuthor("Testy, TEst") .withIssueDate("2015-01-01") - .withEntityType("Project") .build(); isAuthorOfPublicationRelationshipType = relationshipTypeService @@ -666,29 +672,25 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest .withIssueDate("2017-10-17") .withPersonIdentifierFirstName("Donald") .withPersonIdentifierLastName("Smith") - .withEntityType("Person") .build(); - Item author2 = ItemBuilder.createItem(context, col2) + Item author2 = ItemBuilder.createItem(context, col1) .withTitle("Author2") .withIssueDate("2016-02-13") .withPersonIdentifierFirstName("Maria") .withPersonIdentifierLastName("Smith") - .withEntityType("Person") .build(); - Item author3 = ItemBuilder.createItem(context, col2) + Item author3 = ItemBuilder.createItem(context, col1) .withTitle("Author3") .withIssueDate("2016-02-13") .withPersonIdentifierFirstName("Maybe") .withPersonIdentifierLastName("Maybe") - .withEntityType("Person") .build(); - Item publication1 = ItemBuilder.createItem(context, col3) + Item publication1 = ItemBuilder.createItem(context, col2) .withTitle("Publication1") .withIssueDate("2015-01-01") - .withEntityType("Publication") .build(); RelationshipType isAuthorOfPublicationRelationshipType = relationshipTypeService @@ -970,26 +972,23 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest context.turnOffAuthorisationSystem(); - Item publication1 = ItemBuilder.createItem(context, col3) + Item publication1 = ItemBuilder.createItem(context, col2) .withTitle("Publication1") .withIssueDate("2015-01-01") - .withEntityType("Publication") .build(); - Item author2 = ItemBuilder.createItem(context, col2) + Item author2 = ItemBuilder.createItem(context, col1) .withTitle("Author2") .withIssueDate("2016-02-13") .withPersonIdentifierFirstName("Maria") .withPersonIdentifierLastName("Smith") - .withEntityType("Person") .build(); - Item author3 = ItemBuilder.createItem(context, col2) + Item author3 = ItemBuilder.createItem(context, col1) .withTitle("Author3") .withIssueDate("2016-02-13") .withPersonIdentifierFirstName("Maybe") .withPersonIdentifierLastName("Maybe") - .withEntityType("Person") .build(); String adminToken = getAuthToken(admin.getEmail(), password); @@ -1183,26 +1182,23 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest context.turnOffAuthorisationSystem(); - Item publication1 = ItemBuilder.createItem(context, col3) + Item publication1 = ItemBuilder.createItem(context, col2) .withTitle("Publication1") .withIssueDate("2015-01-01") - .withEntityType("Publication") .build(); - Item author2 = ItemBuilder.createItem(context, col2) + Item author2 = ItemBuilder.createItem(context, col1) .withTitle("Author2") .withIssueDate("2016-02-13") .withPersonIdentifierFirstName("Maria") .withPersonIdentifierLastName("Smith") - .withEntityType("Person") .build(); - Item author3 = ItemBuilder.createItem(context, col2) + Item author3 = ItemBuilder.createItem(context, col1) .withTitle("Author3") .withIssueDate("2016-02-13") .withPersonIdentifierFirstName("Maybe") .withPersonIdentifierLastName("Maybe") - .withEntityType("Person") .build(); String adminToken = getAuthToken(admin.getEmail(), password); @@ -1395,12 +1391,11 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest public void deleteRelationship() throws Exception { context.turnOffAuthorisationSystem(); - Item author2 = ItemBuilder.createItem(context, col2) + Item author2 = ItemBuilder.createItem(context, col1) .withTitle("Author2") .withIssueDate("2016-02-13") .withPersonIdentifierFirstName("Maria") .withPersonIdentifierLastName("Smith") - .withEntityType("Person") .build(); String adminToken = getAuthToken(admin.getEmail(), password); @@ -2390,7 +2385,6 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest .withAuthor("Smith, Donald") .withPersonIdentifierFirstName("testingFirstName") .withPersonIdentifierLastName("testingLastName") - .withEntityType("Person") .build(); Relationship relationship3 = RelationshipBuilder @@ -2759,16 +2753,10 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest String journalTitle = "Journal Title Test"; // Create entity items - Item journal = - ItemBuilder.createItem(context, col1).withEntityType("Journal").withTitle(journalTitle).build(); - Item journalVolume = - ItemBuilder.createItem(context, col1).withEntityType("JournalVolume").withTitle("JournalVolume") - .build(); - Item journalIssue = - ItemBuilder.createItem(context, col1).withEntityType("JournalIssue").withTitle("JournalIssue") - .build(); - Item publication = - ItemBuilder.createItem(context, col1).withEntityType("Publication").withTitle("Publication").build(); + Item journal = ItemBuilder.createItem(context, col5).withTitle(journalTitle).build(); + Item journalVolume = ItemBuilder.createItem(context, col6).withTitle("JournalVolume").build(); + Item journalIssue = ItemBuilder.createItem(context, col7).withTitle("JournalIssue").build(); + Item publication = ItemBuilder.createItem(context, col2).withTitle("Publication").build(); // Link Publication-Journal Issue RelationshipBuilder.createRelationshipBuilder(context, journalIssue, publication, isPublicationOfJournalIssue) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipTypeRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipTypeRestControllerIT.java index eb7945023d..efa018a614 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipTypeRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipTypeRestControllerIT.java @@ -110,56 +110,56 @@ public class RelationshipTypeRestControllerIT extends AbstractEntityIntegrationT 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(); - Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build(); + Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1") + .withEntityType("Person").build(); + Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2") + .withEntityType("Person").build(); + Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits") + .withEntityType("OrgUnit").build(); + Collection col4 = CollectionBuilder.createCollection(context, child1).withName("Publications") + .withEntityType("Publication").build(); + Collection col5 = CollectionBuilder.createCollection(context, child1).withName("without entityType") + .build(); Item author1 = ItemBuilder.createItem(context, col1) .withTitle("Author1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald") - .withEntityType("Person") .build(); Item author2 = ItemBuilder.createItem(context, col2) .withTitle("Author2") .withIssueDate("2016-02-13") .withAuthor("Smith, Maria") - .withEntityType("Person") .build(); Item author3 = ItemBuilder.createItem(context, col2) .withTitle("Author3") .withIssueDate("2016-02-13") .withAuthor("Maybe, Maybe") - .withEntityType("Person") .build(); Item orgUnit1 = ItemBuilder.createItem(context, col3) .withTitle("OrgUnit1") .withAuthor("Testy, TEst") .withIssueDate("2015-01-01") - .withEntityType("OrgUnit") .build(); - Item project1 = ItemBuilder.createItem(context, col3) + Item project1 = ItemBuilder.createItem(context, col5) .withTitle("Project1") .withAuthor("Testy, TEst") .withIssueDate("2015-01-01") - .withEntityType("Project") .build(); - Item publication = ItemBuilder.createItem(context, col3) + Item publication = ItemBuilder.createItem(context, col4) .withTitle("Publication1") .withAuthor("Testy, TEst") .withIssueDate("2015-01-01") - .withEntityType("Publication") .build(); - Item publication2 = ItemBuilder.createItem(context, col3) + Item publication2 = ItemBuilder.createItem(context, col4) .withTitle("Publication2") .withIssueDate("2015-01-01") - .withEntityType("Publication") .build(); RelationshipType isOrgUnitOfPersonRelationshipType = relationshipTypeService 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 ffaf6f2da7..a9e4599c2b 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 @@ -5181,8 +5181,8 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration parentCommunity = CommunityBuilder.createCommunity(context) .withName("Parent Community") .build(); - Collection col1 = CollectionBuilder - .createCollection(context, parentCommunity).withName("Collection 1").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1") + .withEntityType("Person").build(); Item author1 = ItemBuilder.createItem(context, col1) .withTitle("Author1") @@ -5190,14 +5190,12 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .build(); Item author2 = ItemBuilder.createItem(context, col1) .withTitle("Author2") .withIssueDate("2016-02-13") .withAuthor("Smith, Maria") - .withEntityType("Person") .build(); //2. One workspace item. diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/csv/CsvExportIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/csv/CsvExportIT.java index 840347dc42..b3be9b0426 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/csv/CsvExportIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/csv/CsvExportIT.java @@ -53,14 +53,14 @@ public class CsvExportIT extends AbstractControllerIntegrationTest { Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) .withName("Sub Community") .build(); - Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build(); + Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1") + .withEntityType("Publication").build(); Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build(); Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build(); Item article = ItemBuilder.createItem(context, col1) .withTitle("Article") .withIssueDate("2017-10-17") - .withEntityType("Publication") .build(); AtomicReference idRef = new AtomicReference<>(); @@ -104,14 +104,14 @@ public class CsvExportIT extends AbstractControllerIntegrationTest { Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) .withName("Sub Community") .build(); - Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build(); + Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1") + .withEntityType("Publication").build(); Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build(); Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build(); Item article = ItemBuilder.createItem(context, col1) .withTitle("Article") .withIssueDate("2017-10-17") - .withEntityType("Publication") .build(); AtomicReference idRef = new AtomicReference<>(); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/csv/CsvImportIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/csv/CsvImportIT.java index 6f8a010495..b2eb36215a 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/csv/CsvImportIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/csv/CsvImportIT.java @@ -84,26 +84,28 @@ public class CsvImportIT extends AbstractEntityIntegrationTest { 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(); - Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build(); + Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1") + .withEntityType("Publication").build(); + Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2") + .withEntityType("Person").build(); + Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits") + .withEntityType("Project").build(); // Create a new Publication (which is an Article) Item article = ItemBuilder.createItem(context, col1) .withTitle("Article") .withIssueDate("2017-10-17") - .withEntityType("Publication") .build(); // Via CSV import, add two Authors to that Publication - Item author1 = validateSpecificItemRelationCreationCsvImport(col1, article, "TestAuthor1", "Person", + Item author1 = validateSpecificItemRelationCreationCsvImport(col2, article, "TestAuthor1", "Person", "isPublicationOfAuthor", "Relationship list size is 1", 1, 0, 0); - Item author2 = validateSpecificItemRelationCreationCsvImport(col1, article, "TestAuthor2", "Person", + Item author2 = validateSpecificItemRelationCreationCsvImport(col2, article, "TestAuthor2", "Person", "isPublicationOfAuthor", "Relationship list size is 1", 1, 1, 0); // Via CSV import, add a Project related to that Publication - Item project = validateSpecificItemRelationCreationCsvImport(col1, article, "TestProject", "Project", + Item project = validateSpecificItemRelationCreationCsvImport(col3, article, "TestProject", "Project", "isPublicationOfProject", "Relationship list size is 1", 1, 0, 0); // Via CSV import, add a new Publication related to both author1 & author2 @@ -130,7 +132,7 @@ public class CsvImportIT extends AbstractEntityIntegrationTest { // Via CSV import add a new Author to the new Publication, as the *third* author. // At this point the new Publication has three authors in this order: author2, author1, author3 - Item author3 = validateSpecificItemRelationCreationCsvImport(col1, article2, "TestAuthor3", "Person", + Item author3 = validateSpecificItemRelationCreationCsvImport(col2, article2, "TestAuthor3", "Person", "isPublicationOfAuthor", "Relationship list size is 1", 1, 2, 0); @@ -304,14 +306,14 @@ public class CsvImportIT extends AbstractEntityIntegrationTest { Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) .withName("Sub Community") .build(); - Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build(); + Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1") + .withEntityType("Publication").build(); Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build(); Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build(); Item article = ItemBuilder.createItem(context, col1) .withTitle("Article") .withIssueDate("2017-10-17") - .withEntityType("Publication") .build(); String csvLineString = "+," + col1.getHandle() + ",TestItemB,Person," + article From 4a5546fa346e9eb6f057970a08b72388f1af8d6f Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Fri, 24 Sep 2021 12:28:45 +0200 Subject: [PATCH 08/24] added supported entity types for external providers --- .../config/spring/api/external-services.xml | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/dspace/config/spring/api/external-services.xml b/dspace/config/spring/api/external-services.xml index 5a938568d5..6d00073525 100644 --- a/dspace/config/spring/api/external-services.xml +++ b/dspace/config/spring/api/external-services.xml @@ -14,6 +14,11 @@ + + + Journal + + @@ -24,6 +29,11 @@ + + + Journal + + @@ -34,6 +44,11 @@ + + + OrgUnit + + @@ -42,6 +57,11 @@ + + + Person + + @@ -52,12 +72,24 @@ + + + Publication + unset + + + + + Publication + unset + + From b2996ab784155990c784577cd1223e98890c8668 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Fri, 24 Sep 2021 12:47:51 +0200 Subject: [PATCH 09/24] fix failed tests --- .../statistics/export/ITIrusExportUsageEventListener.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/statistics/export/ITIrusExportUsageEventListener.java b/dspace-api/src/test/java/org/dspace/statistics/export/ITIrusExportUsageEventListener.java index db27837e9b..1725299d4b 100644 --- a/dspace-api/src/test/java/org/dspace/statistics/export/ITIrusExportUsageEventListener.java +++ b/dspace-api/src/test/java/org/dspace/statistics/export/ITIrusExportUsageEventListener.java @@ -122,16 +122,16 @@ public class ITIrusExportUsageEventListener extends AbstractIntegrationTestWithD entityType = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); community = CommunityBuilder.createCommunity(context).build(); - collection = CollectionBuilder.createCollection(context, community).build(); + collection = CollectionBuilder.createCollection(context, community) + .withEntityType(entityType.getLabel()) + .build(); item = ItemBuilder.createItem(context, collection) - .withEntityType(entityType.getLabel()) .build(); File f = new File(testProps.get("test.bitstream").toString()); bitstream = BitstreamBuilder.createBitstream(context, item, new FileInputStream(f)).build(); itemNotToBeProcessed = ItemBuilder.createItem(context, collection) - .withEntityType(entityType.getLabel()) .withType("Excluded type") .build(); File itemNotToBeProcessedFile = new File(testProps.get("test.bitstream").toString()); From 7140d4ca5c95cdd8b138bf6f6bd587fa7cbad342 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Fri, 24 Sep 2021 13:08:55 +0200 Subject: [PATCH 10/24] fix failed tests --- .../content/WorkspaceItemServiceImpl.java | 2 -- .../dspace/app/rest/ItemRestRepositoryIT.java | 33 +++++++++---------- 2 files changed, 16 insertions(+), 19 deletions(-) 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 cc5dcd8fd1..6b1124b6f4 100644 --- a/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java @@ -121,8 +121,6 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService { MetadataSchema metadataSchema = metadataField.getMetadataSchema(); itemService.addMetadata(context, item, metadataSchema.getName(), metadataField.getElement(), metadataField.getQualifier(), original.getLanguage(), original.getValue()); - } else { - itemService.addMetadata(context, item, "dspace", "entity", "type", null, Constants.UNSET_ENTITY_TYPE); } // Copy template if appropriate 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 1c47825a21..5bf5f980b3 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 @@ -2989,14 +2989,14 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { Community community = CommunityBuilder.createCommunity(context) .withName("Parent Community") .build(); - Collection collection = CollectionBuilder.createCollection(context, community).withName("Collection").build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Collection") + .withEntityType(person.getLabel()).build(); Item item = ItemBuilder.createItem(context, collection) .withTitle("Author1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .build(); context.restoreAuthSystemState(); @@ -3025,12 +3025,12 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { Community community = CommunityBuilder.createCommunity(context) .withName("Parent Community") .build(); - Collection collection = CollectionBuilder.createCollection(context, community).withName("Collection").build(); + Collection collection = CollectionBuilder.createCollection(context, community).withName("Collection") + .withEntityType(publication.getLabel()).build(); Item item = ItemBuilder.createItem(context, collection) .withTitle("Publication1") .withAuthor("Testy, TEst") .withIssueDate("2015-01-01") - .withEntityType("Publication") .build(); context.restoreAuthSystemState(); @@ -3041,7 +3041,7 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$.entityType", is("Publication"))); String adminToken = getAuthToken(admin.getEmail(), password); - getClient(ePersonToken).perform(get("/api/core/items/" + item.getID())) + getClient(adminToken).perform(get("/api/core/items/" + item.getID())) .andExpect(status().isOk()) .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(item))) .andExpect(jsonPath("$.entityType", is("Publication"))); @@ -3664,8 +3664,10 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { parentCommunity = CommunityBuilder.createCommunity(context) .withName("Parent Community") .build(); - Collection col1 = CollectionBuilder - .createCollection(context, parentCommunity).withName("Collection 1").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1") + .withEntityType("Person").build(); + Collection col2 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 2") + .withEntityType("Publication").build(); author1 = ItemBuilder.createItem(context, col1) .withTitle("Author1") @@ -3673,21 +3675,18 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .build(); author2 = ItemBuilder.createItem(context, col1) .withTitle("Author2") .withIssueDate("2016-02-13") .withAuthor("Smith, Maria") - .withEntityType("Person") .build(); - publication1 = ItemBuilder.createItem(context, col1) + publication1 = ItemBuilder.createItem(context, col2) .withTitle("Publication1") .withAuthor("Testy, TEst") .withIssueDate("2015-01-01") - .withEntityType("Publication") .build(); EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); @@ -3728,8 +3727,11 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { parentCommunity = CommunityBuilder.createCommunity(context) .withName("Parent Community") .build(); - Collection col1 = CollectionBuilder - .createCollection(context, parentCommunity).withName("Collection 1").build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1") + .withEntityType("Person").build(); + Collection col2 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 2") + .withEntityType("Publication").build(); author1 = ItemBuilder.createItem(context, col1) .withTitle("Author1") @@ -3737,21 +3739,18 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest { .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .build(); author2 = ItemBuilder.createItem(context, col1) .withTitle("Author2") .withIssueDate("2016-02-13") .withAuthor("Smith, Maria") - .withEntityType("Person") .build(); - publication1 = ItemBuilder.createItem(context, col1) + publication1 = ItemBuilder.createItem(context, col2) .withTitle("Publication1") .withAuthor("Testy, TEst") .withIssueDate("2015-01-01") - .withEntityType("Publication") .build(); EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); From d02dd47bb12b3461775d0a325c83c6a3eb735ad3 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Fri, 24 Sep 2021 15:13:06 +0200 Subject: [PATCH 11/24] implemented flyway script to add new entity type 'unset' --- ...24__Insert_unset_entity_type_to_dspace.sql | 21 +++++++++++++++++++ ...24__Insert_unset_entity_type_to_dspace.sql | 21 +++++++++++++++++++ ...24__Insert_unset_entity_type_to_dspace.sql | 21 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql create mode 100644 dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql create mode 100644 dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql new file mode 100644 index 0000000000..5195b0643f --- /dev/null +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql @@ -0,0 +1,21 @@ +-- +-- 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/ +-- + +-- =============================================================== +-- WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +-- +-- DO NOT MANUALLY RUN THIS DATABASE MIGRATION. IT WILL BE EXECUTED +-- AUTOMATICALLY (IF NEEDED) BY "FLYWAY" WHEN YOU STARTUP DSPACE. +-- http://flywaydb.org/ +-- =============================================================== + +------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------- + +-- Create the new 'unset' entity type +INSERT INTO Entity_type VALUES (0, 'unset'); \ No newline at end of file diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql new file mode 100644 index 0000000000..5195b0643f --- /dev/null +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql @@ -0,0 +1,21 @@ +-- +-- 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/ +-- + +-- =============================================================== +-- WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +-- +-- DO NOT MANUALLY RUN THIS DATABASE MIGRATION. IT WILL BE EXECUTED +-- AUTOMATICALLY (IF NEEDED) BY "FLYWAY" WHEN YOU STARTUP DSPACE. +-- http://flywaydb.org/ +-- =============================================================== + +------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------- + +-- Create the new 'unset' entity type +INSERT INTO Entity_type VALUES (0, 'unset'); \ No newline at end of file diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql new file mode 100644 index 0000000000..5195b0643f --- /dev/null +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql @@ -0,0 +1,21 @@ +-- +-- 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/ +-- + +-- =============================================================== +-- WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +-- +-- DO NOT MANUALLY RUN THIS DATABASE MIGRATION. IT WILL BE EXECUTED +-- AUTOMATICALLY (IF NEEDED) BY "FLYWAY" WHEN YOU STARTUP DSPACE. +-- http://flywaydb.org/ +-- =============================================================== + +------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------- + +-- Create the new 'unset' entity type +INSERT INTO Entity_type VALUES (0, 'unset'); \ No newline at end of file From 302370db72713a1d9fdee92893cf1c78c0e8e32d Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Fri, 24 Sep 2021 16:21:30 +0200 Subject: [PATCH 12/24] update flyway script --- ...1.09.24__Insert_unset_entity_type_to_dspace.sql | 14 +++++++++++++- ...1.09.24__Insert_unset_entity_type_to_dspace.sql | 14 +++++++++++++- ...1.09.24__Insert_unset_entity_type_to_dspace.sql | 14 +++++++++++++- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql index 5195b0643f..4cf7d8d70c 100644 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql @@ -18,4 +18,16 @@ ------------------------------------------------------------------------------------------------------- -- Create the new 'unset' entity type -INSERT INTO Entity_type VALUES (0, 'unset'); \ No newline at end of file +INSERT INTO Entity_type VALUES (0, 'unset'); + +------------------------------------------------------------------------------------------------------- +UPDATE metadatavalue SET dspace_object_id = (SELECT uuid + FROM collection + WHERE template_item_id = dspace_object_id) +WHERE dspace_object_id IN (SELECT template_item_id + FROM Collection) + AND metadata_field_id + IN (SELECT metadata_field_id + FROM metadatafieldregistry mfr LEFT JOIN metadataschemaregistry msr + ON mfr.metadata_schema_id = msr.metadata_schema_id + WHERE msr.short_id = 'dspace' AND mfr.element = 'entity' AND mfr.qualifier = 'type') \ No newline at end of file diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql index 5195b0643f..4cf7d8d70c 100644 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql @@ -18,4 +18,16 @@ ------------------------------------------------------------------------------------------------------- -- Create the new 'unset' entity type -INSERT INTO Entity_type VALUES (0, 'unset'); \ No newline at end of file +INSERT INTO Entity_type VALUES (0, 'unset'); + +------------------------------------------------------------------------------------------------------- +UPDATE metadatavalue SET dspace_object_id = (SELECT uuid + FROM collection + WHERE template_item_id = dspace_object_id) +WHERE dspace_object_id IN (SELECT template_item_id + FROM Collection) + AND metadata_field_id + IN (SELECT metadata_field_id + FROM metadatafieldregistry mfr LEFT JOIN metadataschemaregistry msr + ON mfr.metadata_schema_id = msr.metadata_schema_id + WHERE msr.short_id = 'dspace' AND mfr.element = 'entity' AND mfr.qualifier = 'type') \ No newline at end of file diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql index 5195b0643f..4cf7d8d70c 100644 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql @@ -18,4 +18,16 @@ ------------------------------------------------------------------------------------------------------- -- Create the new 'unset' entity type -INSERT INTO Entity_type VALUES (0, 'unset'); \ No newline at end of file +INSERT INTO Entity_type VALUES (0, 'unset'); + +------------------------------------------------------------------------------------------------------- +UPDATE metadatavalue SET dspace_object_id = (SELECT uuid + FROM collection + WHERE template_item_id = dspace_object_id) +WHERE dspace_object_id IN (SELECT template_item_id + FROM Collection) + AND metadata_field_id + IN (SELECT metadata_field_id + FROM metadatafieldregistry mfr LEFT JOIN metadataschemaregistry msr + ON mfr.metadata_schema_id = msr.metadata_schema_id + WHERE msr.short_id = 'dspace' AND mfr.element = 'entity' AND mfr.qualifier = 'type') \ No newline at end of file From b750e1d25058eed1fd4dc28892be1911e7a3e33b Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Fri, 24 Sep 2021 17:39:06 +0200 Subject: [PATCH 13/24] fix failed tests --- .../org/dspace/app/rest/test/AbstractEntityIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractEntityIntegrationTest.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractEntityIntegrationTest.java index ab3c1acc05..f2c90be986 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractEntityIntegrationTest.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractEntityIntegrationTest.java @@ -41,7 +41,7 @@ public class AbstractEntityIntegrationTest extends AbstractControllerIntegration public void setUp() throws Exception { super.setUp(); - if (entityTypeService.findAll(context).size() > 0) { + if (entityTypeService.findAll(context).size() > 1) { //Don't initialize the setup more than once return; } From d498882d6f130d56c31c1ac634949ee154f977ca Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Fri, 24 Sep 2021 18:22:42 +0200 Subject: [PATCH 14/24] fix failed tests --- .../app/rest/EntityTypeRestRepositoryIT.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) 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 5ab815ef6d..364ce828ca 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 @@ -50,11 +50,12 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { //We expect a 200 OK status .andExpect(status().isOk()) //The type has to be 'discover' - .andExpect(jsonPath("$.page.totalElements", is(7))) + .andExpect(jsonPath("$.page.totalElements", is(8))) //There needs to be a self link to this endpoint .andExpect(jsonPath("$._links.self.href", containsString("api/core/entitytypes"))) //We have 4 facets in the default configuration, they need to all be present in the embedded section .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "unset")), EntityTypeMatcher .matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Publication")), EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Person")), @@ -76,7 +77,7 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { .andExpect(status().isOk()) //The type has to be 'discover' .andExpect(jsonPath("$.page.size", is(5))) - .andExpect(jsonPath("$.page.totalElements", is(7))) + .andExpect(jsonPath("$.page.totalElements", is(8))) .andExpect(jsonPath("$.page.totalPages", is(2))) //There needs to be a self link to this endpoint .andExpect(jsonPath("$._links.self.href", containsString("api/core/entitytypes"))) @@ -87,7 +88,7 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Person")), EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Project")), EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "OrgUnit")), - EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Journal")) + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "unset")) ))); getClient().perform(get("/api/core/entitytypes").param("size", "5").param("page", "1")) @@ -96,13 +97,14 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { .andExpect(status().isOk()) //The type has to be 'discover' .andExpect(jsonPath("$.page.size", is(5))) - .andExpect(jsonPath("$.page.totalElements", is(7))) + .andExpect(jsonPath("$.page.totalElements", is(8))) .andExpect(jsonPath("$.page.totalPages", is(2))) .andExpect(jsonPath("$.page.number", is(1))) //There needs to be a self link to this endpoint .andExpect(jsonPath("$._links.self.href", containsString("api/core/entitytypes"))) //We have 4 facets in the default configuration, they need to all be present in the embedded section .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Journal")), EntityTypeMatcher .matchEntityTypeEntry(entityTypeService.findByEntityType(context, "JournalVolume")), EntityTypeMatcher @@ -133,7 +135,7 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Publication")), EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Person")), - EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Project")) + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "unset")) ))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/core/entitytypes?"), @@ -148,7 +150,7 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { 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.totalElements", is(8))) .andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.number", is(0))); @@ -159,7 +161,7 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "OrgUnit")), EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Journal")), - EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "JournalVolume")) + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Project")) ))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/core/entitytypes?"), @@ -177,7 +179,7 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { 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.totalElements", is(8))) .andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.number", is(1))); } From d6d2f2748357026e3410c82c5f780e578488ed3f Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Wed, 29 Sep 2021 13:34:46 +0200 Subject: [PATCH 15/24] added javaDoc --- .../org/dspace/content/service/EntityTypeService.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java b/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java index 38b905fb74..5dd9c357ae 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java @@ -59,6 +59,15 @@ public interface EntityTypeService extends DSpaceCRUDService { */ public EntityType create(Context context, String entityTypeString) throws SQLException, AuthorizeException; + /** + * Retrieves all entity types related to the collections on which the current user can deposit + * + * @param context DSpace context object + * @return + * @throws SQLException If database error + * @throws SolrServerException If there is a problem in communicating with Solr + * @throws IOException If IO error + */ public List getSubmitAuthorizedTypes(Context context) throws SQLException, SolrServerException, IOException; /** From 3fe4e2d17084a4408012e1133e19fa7cf61eb0e3 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Wed, 29 Sep 2021 13:36:45 +0200 Subject: [PATCH 16/24] fix duplicate method --- .../dspace/content/CollectionServiceImpl.java | 50 +------------------ 1 file changed, 2 insertions(+), 48 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 d81235bb9c..1eba60a532 100644 --- a/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java @@ -928,7 +928,7 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i discoverQuery.setDSpaceObjectFilter(IndexableCollection.TYPE); discoverQuery.setStart(offset); discoverQuery.setMaxResults(limit); - DiscoverResult resp = retrieveCollectionsWithSubmit(context, discoverQuery,community, q); + DiscoverResult resp = retrieveCollectionsWithSubmit(context, discoverQuery, null, community, q); for (IndexableObject solrCollections : resp.getIndexableObjects()) { Collection c = ((IndexableCollection) solrCollections).getIndexedObject(); collections.add(c); @@ -943,56 +943,10 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i DiscoverQuery discoverQuery = new DiscoverQuery(); discoverQuery.setMaxResults(0); discoverQuery.setDSpaceObjectFilter(IndexableCollection.TYPE); - DiscoverResult resp = retrieveCollectionsWithSubmit(context, discoverQuery,community,q); + DiscoverResult resp = retrieveCollectionsWithSubmit(context, discoverQuery, null, community, q); return (int)resp.getTotalSearchResults(); } - /** - * Finds all Indexed Collections where the current user has submit rights. If the user is an Admin, - * this is all Indexed Collections. Otherwise, it includes those collections where - * an indexed "submit" policy lists either the eperson or one of the eperson's groups - * - * @param context DSpace context - * @param discoverQuery - * @param community parent community, could be null - * @param q limit the returned collection to those with metadata values matching the query - * terms. The terms are used to make also a prefix query on SOLR - * so it can be used to implement an autosuggest feature over the collection name - * @return discovery search result objects - * @throws SQLException if something goes wrong - * @throws SearchServiceException if search error - */ - private DiscoverResult retrieveCollectionsWithSubmit(Context context, DiscoverQuery discoverQuery, - Community community, String q) throws SQLException, SearchServiceException { - - StringBuilder query = new StringBuilder(); - EPerson currentUser = context.getCurrentUser(); - if (!authorizeService.isAdmin(context)) { - String userId = ""; - if (currentUser != null) { - userId = currentUser.getID().toString(); - } - query.append("submit:(e").append(userId); - Set groups = groupService.allMemberGroupsSet(context, currentUser); - for (Group group : groups) { - query.append(" OR g").append(group.getID()); - } - query.append(")"); - discoverQuery.addFilterQueries(query.toString()); - } - if (community != null) { - discoverQuery.addFilterQueries("location.comm:" + community.getID().toString()); - } - if (StringUtils.isNotBlank(q)) { - StringBuilder buildQuery = new StringBuilder(); - String escapedQuery = ClientUtils.escapeQueryChars(q); - buildQuery.append(escapedQuery).append(" OR ").append(escapedQuery).append("*"); - discoverQuery.setQuery(buildQuery.toString()); - } - DiscoverResult resp = searchService.search(context, discoverQuery); - return resp; - } - /** * Finds all Indexed Collections where the current user has submit rights. If the user is an Admin, * this is all Indexed Collections. Otherwise, it includes those collections where From bc893656217c912bd9fb30315950d6e4c062464a Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Thu, 7 Oct 2021 19:09:20 +0200 Subject: [PATCH 17/24] Implement community feedbacks --- .../dspace/content/EntityTypeServiceImpl.java | 10 +++ .../content/WorkspaceItemServiceImpl.java | 27 ++++++-- .../content/service/CollectionService.java | 11 +-- .../content/service/EntityTypeService.java | 9 +++ .../main/java/org/dspace/core/Constants.java | 2 +- .../CollectionIndexFactoryImpl.java | 2 +- .../rdbms/EntityTypeServiceInitializer.java | 68 +++++++++++++++++++ ...type_from_item_template_to_collection.sql} | 5 -- ...type_from_item_template_to_collection.sql} | 5 -- ...type_from_item_template_to_collection.sql} | 5 -- .../dspace/app/bulkedit/MetadataImportIT.java | 22 +++++- .../org/dspace/app/rest/csv/CsvExportIT.java | 3 +- 12 files changed, 138 insertions(+), 31 deletions(-) create mode 100644 dspace-api/src/main/java/org/dspace/storage/rdbms/EntityTypeServiceInitializer.java rename dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/{V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql => V7.0_2021.09.24__Move_entity_type_from_item_template_to_collection.sql} (88%) rename dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/{V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql => V7.0_2021.09.24__Move_entity_type_from_item_template_to_collection.sql} (88%) rename dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/{V7.0_2021.09.24__Insert_unset_entity_type_to_dspace.sql => V7.0_2021.09.24__Move_entity_type_from_item_template_to_collection.sql} (88%) diff --git a/dspace-api/src/main/java/org/dspace/content/EntityTypeServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/EntityTypeServiceImpl.java index 2790c36924..0e0c6d51e5 100644 --- a/dspace-api/src/main/java/org/dspace/content/EntityTypeServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/EntityTypeServiceImpl.java @@ -26,6 +26,7 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.service.AuthorizeService; import org.dspace.content.dao.EntityTypeDAO; import org.dspace.content.service.EntityTypeService; +import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.discovery.SolrSearchCore; import org.dspace.discovery.indexobject.IndexableCollection; @@ -168,4 +169,13 @@ public class EntityTypeServiceImpl implements EntityTypeService { return entityTypeDAO.countEntityTypesByNames(context, names); } + @Override + public void initDefaultEntityTypeNames(Context context) throws SQLException, AuthorizeException { + EntityType noneEntityType = this.findByEntityType(context, Constants.ENTITY_TYPE_NONE); + if (Objects.isNull(noneEntityType)) { + noneEntityType = this.create(context, Constants.ENTITY_TYPE_NONE); + this.update(context, noneEntityType); + } + } + } 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 6b1124b6f4..2f49c8fcc2 100644 --- a/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; import org.dspace.app.util.DCInputsReaderException; import org.dspace.app.util.Util; @@ -109,14 +110,18 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService { .addPolicy(context, item, Constants.DELETE, item.getSubmitter(), ResourcePolicy.TYPE_SUBMISSION); - Optional optionalType = collection.getMetadata() - .stream() - .filter(x -> x.getMetadataField().toString('.') - .equalsIgnoreCase("dspace.entity.type")) - .findFirst(); + Optional colEntityType = getDSpaceEntityType(collection); + Optional itemEntityType = getDSpaceEntityType(item); - if (optionalType.isPresent()) { - MetadataValue original = optionalType.get(); + if (colEntityType.isPresent() && itemEntityType.isPresent() && + !StringUtils.equals(colEntityType.get().getValue(), itemEntityType.get().getValue())) { + throw new IllegalStateException("It is not possible to deposite item with entity type : " + + itemEntityType.get().getValue() + " into the collection with different type : " + + colEntityType.get().getValue()); + } + + if (colEntityType.isPresent() && itemEntityType.isEmpty()) { + MetadataValue original = colEntityType.get(); MetadataField metadataField = original.getMetadataField(); MetadataSchema metadataSchema = metadataField.getMetadataSchema(); itemService.addMetadata(context, item, metadataSchema.getName(), metadataField.getElement(), @@ -152,6 +157,14 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService { return workspaceItem; } + private Optional getDSpaceEntityType(DSpaceObject dSpaceObject) { + return dSpaceObject.getMetadata() + .stream() + .filter(x -> x.getMetadataField().toString('.') + .equalsIgnoreCase("dspace.entity.type")) + .findFirst(); + } + @Override public WorkspaceItem create(Context c, WorkflowItem workflowItem) throws SQLException, AuthorizeException { WorkspaceItem workspaceItem = workspaceItemDAO.create(c, new WorkspaceItem()); diff --git a/dspace-api/src/main/java/org/dspace/content/service/CollectionService.java b/dspace-api/src/main/java/org/dspace/content/service/CollectionService.java index 5c64ed532b..54d542c863 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/CollectionService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/CollectionService.java @@ -348,7 +348,7 @@ public interface CollectionService * Returns Collections for which the current user has 'submit' privileges. * NOTE: for better performance, this method retrieves its results from an * index (cache) and does not query the database directly. - * This means that results may be stale or outdated until DS-4524 is resolved" + * This means that results may be stale or outdated until https://github.com/DSpace/DSpace/issues/2853 is resolved" * * @param q limit the returned collection to those with metadata values matching the query terms. * The terms are used to make also a prefix query on SOLR so it can be used to implement @@ -369,7 +369,8 @@ public interface CollectionService * Returns Collections for which the current user has 'submit' privileges. * NOTE: for better performance, this method retrieves its results from an * index (cache) and does not query the database directly. - * This means that results may be stale or outdated until DS-4524 is resolved" + * This means that results may be stale or outdated until + * https://github.com/DSpace/DSpace/issues/2853 is resolved" * * @param q limit the returned collection to those with metadata values matching the query terms. * The terms are used to make also a prefix query on SOLR so it can be used to implement @@ -389,7 +390,8 @@ public interface CollectionService * Counts the number of Collection for which the current user has 'submit' privileges. * NOTE: for better performance, this method retrieves its results from an index (cache) * and does not query the database directly. - * This means that results may be stale or outdated until DS-4524 is resolved." + * This means that results may be stale or outdated until + * https://github.com/DSpace/DSpace/issues/2853 is resolved." * * @param q limit the returned collection to those with metadata values matching the query terms. * The terms are used to make also a prefix query on SOLR so it can be used to implement @@ -407,7 +409,8 @@ public interface CollectionService * Counts the number of Collection for which the current user has 'submit' privileges. * NOTE: for better performance, this method retrieves its results from an index (cache) * and does not query the database directly. - * This means that results may be stale or outdated until DS-4524 is resolved." + * This means that results may be stale or outdated until + * https://github.com/DSpace/DSpace/issues/2853 is resolved." * * @param q limit the returned collection to those with metadata values matching the query terms. * The terms are used to make also a prefix query on SOLR so it can be used to implement diff --git a/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java b/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java index 5dd9c357ae..d0a1a498ce 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java @@ -91,4 +91,13 @@ public interface EntityTypeService extends DSpaceCRUDService { */ public int countEntityTypesByNames(Context context, List names) throws SQLException; + /** + * Initializes the EntityType names, and marks them "permanent". + * + * @param context DSpace context object + * @throws SQLException Database exception + * @throws AuthorizeException Authorization error + */ + public void initDefaultEntityTypeNames(Context context) throws SQLException, AuthorizeException; + } diff --git a/dspace-api/src/main/java/org/dspace/core/Constants.java b/dspace-api/src/main/java/org/dspace/core/Constants.java index 4fae3af642..f730ef6545 100644 --- a/dspace-api/src/main/java/org/dspace/core/Constants.java +++ b/dspace-api/src/main/java/org/dspace/core/Constants.java @@ -230,7 +230,7 @@ public class Constants { /* * Label used by the special entity type assigned when no explicit assignment is defined */ - public static final String UNSET_ENTITY_TYPE = "unset"; + public static final String ENTITY_TYPE_NONE = "none"; /** * Default constructor diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/CollectionIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/CollectionIndexFactoryImpl.java index 57c1ffc4e5..c2bacfe502 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/CollectionIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/CollectionIndexFactoryImpl.java @@ -130,7 +130,7 @@ public class CollectionIndexFactoryImpl extends DSpaceObjectIndexFactoryImpl Date: Fri, 8 Oct 2021 10:13:26 +0200 Subject: [PATCH 18/24] fix failed test --- .../src/test/java/org/dspace/app/packager/PackagerIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/app/packager/PackagerIT.java b/dspace-api/src/test/java/org/dspace/app/packager/PackagerIT.java index ddc2b115d8..bf392dccec 100644 --- a/dspace-api/src/test/java/org/dspace/app/packager/PackagerIT.java +++ b/dspace-api/src/test/java/org/dspace/app/packager/PackagerIT.java @@ -72,13 +72,13 @@ public class PackagerIT extends AbstractIntegrationTestWithDatabase { child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) .withName("Sub Community") .build(); - col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build(); + col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 2") + .withEntityType("Publication").build(); // Create a new Publication (which is an Article) article = ItemBuilder.createItem(context, col1) .withTitle("Article") .withIssueDate("2017-10-17") - .withEntityType("Publication") .build(); tempFile = File.createTempFile("packagerExportTest", ".zip"); From df7231e6b6e4f4a59f6deb27fd5af011811f7565 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Fri, 8 Oct 2021 11:45:10 +0200 Subject: [PATCH 19/24] restore the original tests --- .../app/rest/EntityTypeRestRepositoryIT.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) 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 364ce828ca..9025855139 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 @@ -24,6 +24,7 @@ import org.dspace.builder.EntityTypeBuilder; import org.dspace.content.Community; import org.dspace.content.EntityType; import org.dspace.content.service.EntityTypeService; +import org.dspace.core.Constants; import org.dspace.external.provider.AbstractExternalDataProvider; import org.dspace.external.service.ExternalDataService; import org.hamcrest.Matchers; @@ -50,12 +51,11 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { //We expect a 200 OK status .andExpect(status().isOk()) //The type has to be 'discover' - .andExpect(jsonPath("$.page.totalElements", is(8))) + .andExpect(jsonPath("$.page.totalElements", is(7))) //There needs to be a self link to this endpoint .andExpect(jsonPath("$._links.self.href", containsString("api/core/entitytypes"))) //We have 4 facets in the default configuration, they need to all be present in the embedded section .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( - EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "unset")), EntityTypeMatcher .matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Publication")), EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Person")), @@ -77,7 +77,7 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { .andExpect(status().isOk()) //The type has to be 'discover' .andExpect(jsonPath("$.page.size", is(5))) - .andExpect(jsonPath("$.page.totalElements", is(8))) + .andExpect(jsonPath("$.page.totalElements", is(7))) .andExpect(jsonPath("$.page.totalPages", is(2))) //There needs to be a self link to this endpoint .andExpect(jsonPath("$._links.self.href", containsString("api/core/entitytypes"))) @@ -88,7 +88,7 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Person")), EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Project")), EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "OrgUnit")), - EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "unset")) + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Journal")) ))); getClient().perform(get("/api/core/entitytypes").param("size", "5").param("page", "1")) @@ -97,14 +97,13 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { .andExpect(status().isOk()) //The type has to be 'discover' .andExpect(jsonPath("$.page.size", is(5))) - .andExpect(jsonPath("$.page.totalElements", is(8))) + .andExpect(jsonPath("$.page.totalElements", is(7))) .andExpect(jsonPath("$.page.totalPages", is(2))) .andExpect(jsonPath("$.page.number", is(1))) //There needs to be a self link to this endpoint .andExpect(jsonPath("$._links.self.href", containsString("api/core/entitytypes"))) //We have 4 facets in the default configuration, they need to all be present in the embedded section .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( - EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Journal")), EntityTypeMatcher .matchEntityTypeEntry(entityTypeService.findByEntityType(context, "JournalVolume")), EntityTypeMatcher @@ -135,7 +134,7 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Publication")), EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Person")), - EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "unset")) + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Project")) ))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/core/entitytypes?"), @@ -150,7 +149,7 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { Matchers.containsString("/api/core/entitytypes?"), Matchers.containsString("page=2"), Matchers.containsString("size=3")))) .andExpect(jsonPath("$.page.size", is(3))) - .andExpect(jsonPath("$.page.totalElements", is(8))) + .andExpect(jsonPath("$.page.totalElements", is(7))) .andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.number", is(0))); @@ -161,7 +160,7 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "OrgUnit")), EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Journal")), - EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Project")) + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "JournalVolume")) ))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/core/entitytypes?"), @@ -179,7 +178,7 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { Matchers.containsString("/api/core/entitytypes?"), Matchers.containsString("page=2"), Matchers.containsString("size=3")))) .andExpect(jsonPath("$.page.size", is(3))) - .andExpect(jsonPath("$.page.totalElements", is(8))) + .andExpect(jsonPath("$.page.totalElements", is(7))) .andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.number", is(1))); } From 62917409a40e6f198684b665c859f5e8a95028b2 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Fri, 8 Oct 2021 15:06:21 +0200 Subject: [PATCH 20/24] add JavaDoc --- .../app/csv/CSVMetadataImportReferenceIT.java | 19 +++++++++++++++++- .../repository/CollectionRestRepository.java | 20 +++++++++++++++++++ .../repository/EntityTypeRestRepository.java | 13 ++++++++++++ .../ExternalSourceRestRepository.java | 8 ++++++++ .../app/rest/EntityTypeRestRepositoryIT.java | 1 - .../config/spring/api/external-services.xml | 4 ++-- 6 files changed, 61 insertions(+), 4 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/app/csv/CSVMetadataImportReferenceIT.java b/dspace-api/src/test/java/org/dspace/app/csv/CSVMetadataImportReferenceIT.java index df1a9e34d0..5933dff71c 100644 --- a/dspace-api/src/test/java/org/dspace/app/csv/CSVMetadataImportReferenceIT.java +++ b/dspace-api/src/test/java/org/dspace/app/csv/CSVMetadataImportReferenceIT.java @@ -55,6 +55,7 @@ import org.junit.Test; public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDatabase { //Common collection to utilize for test + private Collection col; private Collection col1; private Collection col2; @@ -76,6 +77,10 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withName("Parent Community") .build(); + col = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection") + .build(); + col1 = CollectionBuilder.createCollection(context, parentCommunity) .withEntityType("Person") .withName("Collection 1") @@ -83,7 +88,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat col2 = CollectionBuilder.createCollection(context, parentCommunity) .withEntityType("Publication") - .withName("Collection 1") + .withName("Collection 2") .build(); context.turnOffAuthorisationSystem(); @@ -149,6 +154,18 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat cleanupImportItems(items); } + @Test + public void testSingleMdRefIntoCollectionWithoutEntityTypeTest() throws Exception { + String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other", + "+,Person,," + col.getHandle() + ",0", + "+,Publication,dc.identifier.other:0," + col.getHandle() + ",1"}; + Item[] items = runImport(csv); + assertRelationship(items[1], items[0], 1, "left", 0); + + // remove created items + cleanupImportItems(items); + } + /** * return an array of items given a representation of a CSV as a string array * diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java index 36c53fd33c..4a769709d3 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java @@ -222,6 +222,16 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository findSubmitAuthorizedByEntityType( @Parameter(value = "query") String query, @@ -244,6 +254,16 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository findSubmitAuthorizedByCommunityAndEntityType( @Parameter(value = "query") String query, diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java index 341a8111e3..eec67b6fc9 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/EntityTypeRestRepository.java @@ -63,6 +63,12 @@ public class EntityTypeRestRepository extends DSpaceRestRepository findAllByAuthorizedCollection(Pageable pageable) { try { @@ -84,6 +90,13 @@ public class EntityTypeRestRepository extends DSpaceRestRepository findAllByAuthorizedExternalSource(Pageable pageable) { try { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalSourceRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalSourceRestRepository.java index 474264520b..7888603f19 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalSourceRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalSourceRestRepository.java @@ -99,6 +99,14 @@ public class ExternalSourceRestRepository extends DSpaceRestRepository findByEntityType(Context context, Pageable pageable, 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 9025855139..5ab815ef6d 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 @@ -24,7 +24,6 @@ import org.dspace.builder.EntityTypeBuilder; import org.dspace.content.Community; import org.dspace.content.EntityType; import org.dspace.content.service.EntityTypeService; -import org.dspace.core.Constants; import org.dspace.external.provider.AbstractExternalDataProvider; import org.dspace.external.service.ExternalDataService; import org.hamcrest.Matchers; diff --git a/dspace/config/spring/api/external-services.xml b/dspace/config/spring/api/external-services.xml index 6d00073525..9e28e5d559 100644 --- a/dspace/config/spring/api/external-services.xml +++ b/dspace/config/spring/api/external-services.xml @@ -75,7 +75,7 @@ Publication - unset + none @@ -87,7 +87,7 @@ Publication - unset + none From 980ac528a26f69f85edf9f224e19e0085f439386 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Mon, 11 Oct 2021 15:07:08 +0200 Subject: [PATCH 21/24] Implement community feedbacks --- .../spring/spring-dspace-core-services.xml | 1 + .../config/spring/api/external-services.xml | 2 +- .../app/rest/EntityTypeRestRepositoryIT.java | 24 ++++++++++++------- .../rest/ExternalSourcesRestControllerIT.java | 3 +-- 4 files changed, 18 insertions(+), 12 deletions(-) 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 6dcaa43b08..cdea1c81fe 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 @@ -44,5 +44,6 @@ + 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 cf36e7fd25..ac163d3581 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 @@ -65,7 +65,7 @@ - Publication + Person 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 5ab815ef6d..5fe4abf728 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 @@ -24,6 +24,7 @@ import org.dspace.builder.EntityTypeBuilder; import org.dspace.content.Community; import org.dspace.content.EntityType; import org.dspace.content.service.EntityTypeService; +import org.dspace.core.Constants; import org.dspace.external.provider.AbstractExternalDataProvider; import org.dspace.external.service.ExternalDataService; import org.hamcrest.Matchers; @@ -50,11 +51,13 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { //We expect a 200 OK status .andExpect(status().isOk()) //The type has to be 'discover' - .andExpect(jsonPath("$.page.totalElements", is(7))) + .andExpect(jsonPath("$.page.totalElements", is(8))) //There needs to be a self link to this endpoint .andExpect(jsonPath("$._links.self.href", containsString("api/core/entitytypes"))) //We have 4 facets in the default configuration, they need to all be present in the embedded section .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, + Constants.ENTITY_TYPE_NONE)), EntityTypeMatcher .matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Publication")), EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Person")), @@ -76,18 +79,19 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { .andExpect(status().isOk()) //The type has to be 'discover' .andExpect(jsonPath("$.page.size", is(5))) - .andExpect(jsonPath("$.page.totalElements", is(7))) + .andExpect(jsonPath("$.page.totalElements", is(8))) .andExpect(jsonPath("$.page.totalPages", is(2))) //There needs to be a self link to this endpoint .andExpect(jsonPath("$._links.self.href", containsString("api/core/entitytypes"))) //We have 4 facets in the default configuration, they need to all be present in the embedded section .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, + Constants.ENTITY_TYPE_NONE)), EntityTypeMatcher .matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Publication")), EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Person")), EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Project")), - EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "OrgUnit")), - EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Journal")) + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "OrgUnit")) ))); getClient().perform(get("/api/core/entitytypes").param("size", "5").param("page", "1")) @@ -96,13 +100,14 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { .andExpect(status().isOk()) //The type has to be 'discover' .andExpect(jsonPath("$.page.size", is(5))) - .andExpect(jsonPath("$.page.totalElements", is(7))) + .andExpect(jsonPath("$.page.totalElements", is(8))) .andExpect(jsonPath("$.page.totalPages", is(2))) .andExpect(jsonPath("$.page.number", is(1))) //There needs to be a self link to this endpoint .andExpect(jsonPath("$._links.self.href", containsString("api/core/entitytypes"))) //We have 4 facets in the default configuration, they need to all be present in the embedded section .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Journal")), EntityTypeMatcher .matchEntityTypeEntry(entityTypeService.findByEntityType(context, "JournalVolume")), EntityTypeMatcher @@ -133,7 +138,8 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Publication")), EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Person")), - EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Project")) + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, + Constants.ENTITY_TYPE_NONE)) ))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/core/entitytypes?"), @@ -148,7 +154,7 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { 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.totalElements", is(8))) .andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.number", is(0))); @@ -159,7 +165,7 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { .andExpect(jsonPath("$._embedded.entitytypes", containsInAnyOrder( EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "OrgUnit")), EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Journal")), - EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "JournalVolume")) + EntityTypeMatcher.matchEntityTypeEntry(entityTypeService.findByEntityType(context, "Project")) ))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/core/entitytypes?"), @@ -177,7 +183,7 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { 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.totalElements", is(8))) .andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.number", is(1))); } 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 1a9db10df1..c974c89390 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 @@ -145,10 +145,9 @@ public class ExternalSourcesRestControllerIT extends AbstractControllerIntegrati .andExpect(status().isOk()) .andExpect(jsonPath("$._embedded.externalsources", Matchers.contains( ExternalSourceMatcher.matchExternalSource("mock", "mock", false), - ExternalSourceMatcher.matchExternalSource("orcid", "orcid", false), ExternalSourceMatcher.matchExternalSource("pubmed", "pubmed", false) ))) - .andExpect(jsonPath("$.page.totalElements", Matchers.is(3))); + .andExpect(jsonPath("$.page.totalElements", Matchers.is(2))); getClient().perform(get("/api/integration/externalsources/search/findByEntityType") .param("entityType", "Journal")) From 67ed399c7b5d1f97b37c4435c51d821280e2c50e Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Thu, 14 Oct 2021 11:39:28 +0200 Subject: [PATCH 22/24] added test to verify IllegalStateException --- .../content/WorkspaceItemServiceImpl.java | 31 ++++++++-------- .../rest/WorkspaceItemRestRepositoryIT.java | 37 +++++++++++++++++++ 2 files changed, 53 insertions(+), 15 deletions(-) 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 ea5edb7601..d891dcf638 100644 --- a/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java @@ -12,6 +12,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.UUID; @@ -121,18 +122,20 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService { authorizeService .addPolicy(context, item, Constants.DELETE, item.getSubmitter(), ResourcePolicy.TYPE_SUBMISSION); + // Copy template if appropriate + Item templateItem = collection.getTemplateItem(); Optional colEntityType = getDSpaceEntityType(collection); - Optional itemEntityType = getDSpaceEntityType(item); + Optional templateItemEntityType = getDSpaceEntityType(templateItem); - if (colEntityType.isPresent() && itemEntityType.isPresent() && - !StringUtils.equals(colEntityType.get().getValue(), itemEntityType.get().getValue())) { - throw new IllegalStateException("It is not possible to deposite item with entity type : " + - itemEntityType.get().getValue() + " into the collection with different type : " + - colEntityType.get().getValue()); + if (colEntityType.isPresent() && templateItemEntityType.isPresent() && + !StringUtils.equals(colEntityType.get().getValue(), templateItemEntityType.get().getValue())) { + throw new IllegalStateException("The template item has entity type : (" + + templateItemEntityType.get().getValue() + ") different than collection entity type : " + + colEntityType.get().getValue()); } - if (colEntityType.isPresent() && itemEntityType.isEmpty()) { + if (colEntityType.isPresent() && templateItemEntityType.isEmpty()) { MetadataValue original = colEntityType.get(); MetadataField metadataField = original.getMetadataField(); MetadataSchema metadataSchema = metadataField.getMetadataSchema(); @@ -140,9 +143,6 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService { metadataField.getQualifier(), original.getLanguage(), original.getValue()); } - // Copy template if appropriate - Item templateItem = collection.getTemplateItem(); - if (template && (templateItem != null)) { List md = itemService.getMetadata(templateItem, Item.ANY, Item.ANY, Item.ANY, Item.ANY); @@ -170,11 +170,12 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService { } private Optional getDSpaceEntityType(DSpaceObject dSpaceObject) { - return dSpaceObject.getMetadata() - .stream() - .filter(x -> x.getMetadataField().toString('.') - .equalsIgnoreCase("dspace.entity.type")) - .findFirst(); + return Objects.nonNull(dSpaceObject) ? dSpaceObject.getMetadata() + .stream() + .filter(x -> x.getMetadataField().toString('.') + .equalsIgnoreCase("dspace.entity.type")) + .findFirst() + : Optional.empty(); } @Override 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 a9e4599c2b..54d808d94b 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,6 +67,7 @@ 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.ItemService; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; import org.dspace.eperson.factory.EPersonServiceFactory; @@ -85,6 +86,8 @@ import org.springframework.test.web.servlet.MvcResult; */ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegrationTest { + @Autowired + private ItemService itemService; @Autowired private ConfigurationService configurationService; @@ -5297,4 +5300,38 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration } + @Test + public void invalidCollectionConfigurationPreventItemCreationTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Collection col = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 1") + .withSubmitterGroup(eperson) + .withTemplateItem() + .withEntityType("Person") + .build(); + + Item templateItem = col.getTemplateItem(); + itemService.addMetadata(context, templateItem, "dspace", "entity", "type", null, "Publication"); + + String authToken = getAuthToken(eperson.getEmail(), password); + + InputStream pdf = getClass().getResourceAsStream("simple-article.pdf"); + MockMultipartFile pdfFile = new MockMultipartFile("file", "/local/path/myfile.pdf", "application/pdf", pdf); + + context.restoreAuthSystemState(); + + try { + getClient(authToken).perform(fileUpload("/api/submission/workspaceitems") + .file(pdfFile)) + .andExpect(status().is(500)); + } finally { + pdf.close(); + } + } + } From e6cfdf7df6e2f3c7e11b8fe177a794e7e93dc47c Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Fri, 15 Oct 2021 17:37:19 +0200 Subject: [PATCH 23/24] Implement community feedbacks --- .../org/dspace/content/CollectionServiceImpl.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 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 5f1d1e0c43..58085ef0d8 100644 --- a/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java @@ -17,6 +17,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.MissingResourceException; +import java.util.Objects; import java.util.Set; import java.util.UUID; @@ -995,15 +996,11 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i query.append(")"); discoverQuery.addFilterQueries(query.toString()); } - StringBuilder buildFilter = new StringBuilder(); - if (community != null) { - buildFilter.append("location.comm:").append(community.getID().toString()); + if (Objects.nonNull(community)) { + discoverQuery.addFilterQueries("location.comm:" + community.getID().toString()); } if (StringUtils.isNotBlank(entityType)) { - if (buildFilter.length() > 0) { - buildFilter.append(" AND "); - } - buildFilter.append("search.entitytype:").append(entityType); + discoverQuery.addFilterQueries("search.entitytype:" + entityType); } if (StringUtils.isNotBlank(q)) { StringBuilder buildQuery = new StringBuilder(); @@ -1011,7 +1008,6 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i buildQuery.append(escapedQuery).append(" OR ").append(escapedQuery).append("*"); discoverQuery.setQuery(buildQuery.toString()); } - discoverQuery.addFilterQueries(buildFilter.toString()); DiscoverResult resp = searchService.search(context, discoverQuery); return resp; } From 534a16254cadf17b55edcf80e7b1b3499deb347b Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Mon, 18 Oct 2021 15:42:37 +0200 Subject: [PATCH 24/24] minor update --- ...09.24__Move_entity_type_from_item_template_to_collection.sql | 2 +- ...09.24__Move_entity_type_from_item_template_to_collection.sql | 2 +- ...09.24__Move_entity_type_from_item_template_to_collection.sql | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.09.24__Move_entity_type_from_item_template_to_collection.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.09.24__Move_entity_type_from_item_template_to_collection.sql index f750a2542e..5a6abda041 100644 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.09.24__Move_entity_type_from_item_template_to_collection.sql +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.09.24__Move_entity_type_from_item_template_to_collection.sql @@ -25,4 +25,4 @@ WHERE dspace_object_id IN (SELECT template_item_id IN (SELECT metadata_field_id FROM metadatafieldregistry mfr LEFT JOIN metadataschemaregistry msr ON mfr.metadata_schema_id = msr.metadata_schema_id - WHERE msr.short_id = 'dspace' AND mfr.element = 'entity' AND mfr.qualifier = 'type') \ No newline at end of file + WHERE msr.short_id = 'dspace' AND mfr.element = 'entity' AND mfr.qualifier = 'type'); \ No newline at end of file diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.09.24__Move_entity_type_from_item_template_to_collection.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.09.24__Move_entity_type_from_item_template_to_collection.sql index f750a2542e..5a6abda041 100644 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.09.24__Move_entity_type_from_item_template_to_collection.sql +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2021.09.24__Move_entity_type_from_item_template_to_collection.sql @@ -25,4 +25,4 @@ WHERE dspace_object_id IN (SELECT template_item_id IN (SELECT metadata_field_id FROM metadatafieldregistry mfr LEFT JOIN metadataschemaregistry msr ON mfr.metadata_schema_id = msr.metadata_schema_id - WHERE msr.short_id = 'dspace' AND mfr.element = 'entity' AND mfr.qualifier = 'type') \ No newline at end of file + WHERE msr.short_id = 'dspace' AND mfr.element = 'entity' AND mfr.qualifier = 'type'); \ No newline at end of file diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.09.24__Move_entity_type_from_item_template_to_collection.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.09.24__Move_entity_type_from_item_template_to_collection.sql index f750a2542e..5a6abda041 100644 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.09.24__Move_entity_type_from_item_template_to_collection.sql +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2021.09.24__Move_entity_type_from_item_template_to_collection.sql @@ -25,4 +25,4 @@ WHERE dspace_object_id IN (SELECT template_item_id IN (SELECT metadata_field_id FROM metadatafieldregistry mfr LEFT JOIN metadataschemaregistry msr ON mfr.metadata_schema_id = msr.metadata_schema_id - WHERE msr.short_id = 'dspace' AND mfr.element = 'entity' AND mfr.qualifier = 'type') \ No newline at end of file + WHERE msr.short_id = 'dspace' AND mfr.element = 'entity' AND mfr.qualifier = 'type'); \ No newline at end of file