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 1f0496df25..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; @@ -940,7 +941,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); @@ -955,7 +956,7 @@ 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(); } @@ -966,6 +967,7 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i * * @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 @@ -975,7 +977,8 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i * @throws SearchServiceException if search error */ private DiscoverResult retrieveCollectionsWithSubmit(Context context, DiscoverQuery discoverQuery, - Community community, String q) throws SQLException, SearchServiceException { + String entityType, Community community, String q) + throws SQLException, SearchServiceException { StringBuilder query = new StringBuilder(); EPerson currentUser = context.getCurrentUser(); @@ -985,6 +988,7 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i 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()); @@ -992,9 +996,12 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i query.append(")"); discoverQuery.addFilterQueries(query.toString()); } - if (community != null) { + if (Objects.nonNull(community)) { discoverQuery.addFilterQueries("location.comm:" + community.getID().toString()); } + if (StringUtils.isNotBlank(entityType)) { + discoverQuery.addFilterQueries("search.entitytype:" + entityType); + } if (StringUtils.isNotBlank(q)) { StringBuilder buildQuery = new StringBuilder(); String escapedQuery = ClientUtils.escapeQueryChars(q); @@ -1004,4 +1011,32 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i 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/EntityTypeServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/EntityTypeServiceImpl.java index 4577054ff0..0e0c6d51e5 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,31 @@ */ 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.Constants; 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 +42,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 +119,63 @@ 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; + } + + @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); + } + + @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 d1a761268c..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,8 +12,11 @@ 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; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; import org.dspace.app.util.DCInputsReaderException; import org.dspace.app.util.Util; @@ -119,10 +122,27 @@ 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 templateItemEntityType = getDSpaceEntityType(templateItem); + + 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() && templateItemEntityType.isEmpty()) { + MetadataValue original = colEntityType.get(); + MetadataField metadataField = original.getMetadataField(); + MetadataSchema metadataSchema = metadataField.getMetadataSchema(); + itemService.addMetadata(context, item, metadataSchema.getName(), metadataField.getElement(), + metadataField.getQualifier(), original.getLanguage(), original.getValue()); + } + if (template && (templateItem != null)) { List md = itemService.getMetadata(templateItem, Item.ANY, Item.ANY, Item.ANY, Item.ANY); @@ -149,6 +169,15 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService { return workspaceItem; } + private Optional getDSpaceEntityType(DSpaceObject dSpaceObject) { + return Objects.nonNull(dSpaceObject) ? dSpaceObject.getMetadata() + .stream() + .filter(x -> x.getMetadataField().toString('.') + .equalsIgnoreCase("dspace.entity.type")) + .findFirst() + : Optional.empty(); + } + @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/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/CollectionService.java b/dspace-api/src/main/java/org/dspace/content/service/CollectionService.java index 2580e74b99..3a48065795 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 @@ -364,8 +364,30 @@ 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 + * 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 + * index (cache) and does not query the database directly. + * 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 * an autosuggest feature over the collection name @@ -384,8 +406,9 @@ 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 * an autosuggest feature over the collection name @@ -397,4 +420,25 @@ 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 + * 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 + * 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/content/service/EntityTypeService.java b/dspace-api/src/main/java/org/dspace/content/service/EntityTypeService.java index f4d9a15bb2..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 @@ -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,46 @@ public interface EntityTypeService extends DSpaceCRUDService { * @throws AuthorizeException If something geos wrong with authorizations */ 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; + + /** + * + * @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; + + /** + * 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 6dcb7d9df2..f730ef6545 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 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 5130be6cd7..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 @@ -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,6 +113,7 @@ public class CollectionIndexFactoryImpl extends DSpaceObjectIndexFactoryImpl toIgnoreMetadataFields = SearchUtils.getIgnoredMetadataFields(collection.getType()); addContainerMetadataField(doc, highlightedMetadataFields, toIgnoreMetadataFields, "dc.description", @@ -126,6 +129,12 @@ public class CollectionIndexFactoryImpl extends DSpaceObjectIndexFactoryImpl 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 210d8a24a8..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 @@ -21,7 +21,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 @@ -30,7 +30,7 @@ import org.dspace.external.provider.ExternalDataProvider; * * @author Kim Shepherd */ -public class SHERPAv2JournalDataProvider implements ExternalDataProvider { +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/main/java/org/dspace/storage/rdbms/EntityTypeServiceInitializer.java b/dspace-api/src/main/java/org/dspace/storage/rdbms/EntityTypeServiceInitializer.java new file mode 100644 index 0000000000..ebf790900b --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/storage/rdbms/EntityTypeServiceInitializer.java @@ -0,0 +1,68 @@ +/** + * 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.storage.rdbms; +import org.apache.logging.log4j.Logger; +import org.dspace.content.service.EntityTypeService; +import org.dspace.core.Context; +import org.flywaydb.core.api.callback.Callback; +import org.flywaydb.core.api.callback.Event; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * Callback method to ensure that the default EntityTypes are created in the database + * AFTER the database migration completes. + * + * @author Mykhaylo Boychuk (mykhaylo.boychuk at 4science.it) + */ +public class EntityTypeServiceInitializer implements Callback { + + private final Logger log = org.apache.logging.log4j.LogManager.getLogger(EntityTypeServiceInitializer.class); + + @Autowired(required = true) + private EntityTypeService entityTypeService; + + private void initEntityTypes() { + // After every migrate, ensure default EntityTypes are setup correctly. + Context context = null; + try { + context = new Context(); + context.turnOffAuthorisationSystem(); + // While it's not really a formal "registry", we need to ensure the + // default, required EntityTypes exist in the DSpace database + entityTypeService.initDefaultEntityTypeNames(context); + context.restoreAuthSystemState(); + // Commit changes and close context + context.complete(); + } catch (Exception e) { + log.error("Error attempting to add/update default DSpace EntityTypes", e); + throw new RuntimeException(e); + } finally { + // Clean up our context, if it still exists & it was never completed + if (context != null && context.isValid()) { + context.abort(); + } + } + } + + @Override + public boolean supports(Event event, org.flywaydb.core.api.callback.Context context) { + // Must run AFTER all migrations complete, since it is dependent on Hibernate + return event.equals(Event.AFTER_MIGRATE); + } + + @Override + public boolean canHandleInTransaction(Event event, org.flywaydb.core.api.callback.Context context) { + return true; + } + + @Override + public void handle(Event event, org.flywaydb.core.api.callback.Context context) { + initEntityTypes(); + } + +} \ No newline at end of file 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 new file mode 100644 index 0000000000..5a6abda041 --- /dev/null +++ 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 @@ -0,0 +1,28 @@ +-- +-- 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/ +-- =============================================================== + +------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------- +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__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 new file mode 100644 index 0000000000..5a6abda041 --- /dev/null +++ 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 @@ -0,0 +1,28 @@ +-- +-- 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/ +-- =============================================================== + +------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------- +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__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 new file mode 100644 index 0000000000..5a6abda041 --- /dev/null +++ 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 @@ -0,0 +1,28 @@ +-- +-- 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/ +-- =============================================================== + +------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------- +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/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 590fd57cb6..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 @@ -20,6 +20,11 @@ + + + Journal + + @@ -30,6 +35,11 @@ + + + Journal + + @@ -40,6 +50,11 @@ + + + OrgUnit + + @@ -48,6 +63,11 @@ + + + Person + + 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 280f4f4ff6..1bd7242df0 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 @@ -54,7 +54,9 @@ public class MetadataImportIT extends AbstractIntegrationTestWithDatabase { private final RelationshipService relationshipService = ContentServiceFactory.getInstance().getRelationshipService(); - Collection collection; + private Collection collection; + private Collection publicationCollection; + private Collection personCollection; @Before @Override @@ -63,6 +65,12 @@ public class MetadataImportIT extends AbstractIntegrationTestWithDatabase { 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(); } @@ -84,6 +92,24 @@ public class MetadataImportIT extends AbstractIntegrationTestWithDatabase { context.restoreAuthSystemState(); } + @Test + public void metadataImportIntoCollectionWithEntityTypeTest() throws Exception { + String[] csv = {"id,collection,dc.title,dc.contributor.author", + "+," + publicationCollection.getHandle() + ",\"Test Import 1\"," + "\"Donald, SmithImported\""}; + performImportScript(csv); + Item importedItem = findItemByName("Test Import 1"); + assertTrue(StringUtils.equals(itemService.getMetadata(importedItem, "dc", "contributor", "author", Item.ANY) + .get(0).getValue(), "Donald, SmithImported")); + assertTrue(StringUtils.equals(itemService.getMetadata(importedItem, "dspace", "entity", "type", Item.ANY) + .get(0).getValue(), "Publication")); + eperson = ePersonService.findByEmail(context, eperson.getEmail()); + assertEquals(importedItem.getSubmitter(), eperson); + + context.turnOffAuthorisationSystem(); + itemService.delete(context, itemService.find(context, importedItem.getID())); + context.restoreAuthSystemState(); + } + @Test(expected = ParseException.class) public void metadataImportWithoutEPersonParameterTest() throws IllegalAccessException, InstantiationException, ParseException { @@ -107,7 +133,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(); @@ -116,7 +142,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"); @@ -130,11 +156,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(); @@ -145,7 +171,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"); @@ -158,7 +184,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( @@ -174,7 +200,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(); @@ -184,7 +210,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(0, itemService.getMetadata(item, "dc", "contributor", "author", Item.ANY).size()); 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 0eff180101..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,7 +55,9 @@ import org.junit.Test; public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDatabase { //Common collection to utilize for test + private Collection col; private Collection col1; + private Collection col2; private final RelationshipService relationshipService = ContentServiceFactory.getInstance().getRelationshipService(); @@ -75,8 +77,19 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withName("Parent Community") .build(); - col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + col = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection") + .build(); + col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType("Person") + .withName("Collection 1") + .build(); + + col2 = CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType("Publication") + .withName("Collection 2") + .build(); context.turnOffAuthorisationSystem(); @@ -133,7 +146,19 @@ 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); + + // remove created items + 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); @@ -180,7 +205,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); // remove created items @@ -196,7 +221,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); @@ -213,7 +238,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); @@ -234,11 +259,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); // remove created items @@ -258,7 +282,6 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .build(); Item person2 = ItemBuilder.createItem(context, col1) .withTitle("Author2") @@ -266,11 +289,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); @@ -291,12 +313,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); @@ -319,7 +340,6 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .build(); Item person2 = ItemBuilder.createItem(context, col1) .withTitle("Person2") @@ -327,7 +347,6 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, John") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("John") - .withEntityType("Person") .build(); context.restoreAuthSystemState(); @@ -335,7 +354,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); @@ -353,7 +372,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); // remove created items @@ -397,7 +416,6 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .withIdentifierOther("1") .build(); ItemBuilder.createItem(context, col1) @@ -406,7 +424,6 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, John") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("John") - .withEntityType("Person") .withIdentifierOther("1") .build(); @@ -428,7 +445,6 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat .withAuthor("Smith, Donald") .withPersonIdentifierLastName("Smith") .withPersonIdentifierFirstName("Donald") - .withEntityType("Person") .withIdentifierOther("1") .build(); context.restoreAuthSystemState(); @@ -488,11 +504,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" + @@ -506,11 +532,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" + @@ -525,29 +561,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(); @@ -569,8 +616,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); @@ -587,13 +634,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); } @@ -605,11 +651,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/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"); diff --git a/dspace-api/src/test/java/org/dspace/builder/CollectionBuilder.java b/dspace-api/src/test/java/org/dspace/builder/CollectionBuilder.java index eece873380..0db1f6900f 100644 --- a/dspace-api/src/test/java/org/dspace/builder/CollectionBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/CollectionBuilder.java @@ -100,6 +100,10 @@ public class CollectionBuilder extends AbstractDSpaceObjectBuilder { 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-api/src/test/java/org/dspace/builder/ItemBuilder.java b/dspace-api/src/test/java/org/dspace/builder/ItemBuilder.java index 365ca57889..f00104014d 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/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-api/src/test/java/org/dspace/statistics/export/ITIrusExportUsageEventListener.java b/dspace-api/src/test/java/org/dspace/statistics/export/ITIrusExportUsageEventListener.java index c4b493159a..e28e8284a2 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 @@ -123,16 +123,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()); 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/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/CollectionRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/CollectionRestRepository.java index 65d4ef4e6b..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 @@ -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; @@ -41,10 +42,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 +115,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.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); + } + } + + /** + * Returns Collections for which the current user has 'submit' privileges limited by parent community. + * + * @param query The query used in the lookup + * @param communityUuid UUID of the parent community + * @param entityTypeLabel The EntityType label object that will be used to limit the returned collection + * to those related to given entity type + * @param pageable The pagination information + * @return + */ + @SearchRestMethod(name = "findSubmitAuthorizedByCommunityAndEntityType") + public Page 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/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..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 @@ -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); + } + } + + /** + * Retrieves all entity types related to the collections + * on which the current user can deposit and supported by External provider + * + * @param pageable The pagination information + * @return + */ + @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/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/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..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 @@ -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,26 @@ 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/CollectionRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionRestRepositoryIT.java index a9e8dadbe7..92fdecf824 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; @@ -58,11 +61,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; @@ -3220,4 +3225,342 @@ 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) + ))); + } + + @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-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 da2be08fd4..8437ad9068 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,19 +14,34 @@ 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.matcher.RelationshipTypeMatcher; 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.RelationshipType; 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; 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; @@ -38,11 +53,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")), @@ -64,18 +81,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")) @@ -84,13 +102,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 @@ -121,7 +140,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?"), @@ -136,7 +156,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))); @@ -147,7 +167,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?"), @@ -165,7 +185,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))); } @@ -203,4 +223,219 @@ public class EntityTypeRestRepositoryIT extends AbstractEntityIntegrationTest { ))); } + @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 c6573dd744..05ca955e5c 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")) @@ -127,4 +139,170 @@ 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("pubmed", "pubmed", false) + ))) + .andExpect(jsonPath("$.page.totalElements", Matchers.is(2))); + + 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))); + } + + @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); + } + } + } 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 d865a94761..372ab084dd 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 @@ -3011,14 +3011,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(); @@ -3047,12 +3047,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(); @@ -3063,7 +3063,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"))); @@ -3686,8 +3686,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") @@ -3695,21 +3697,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(); @@ -3750,8 +3749,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") @@ -3759,21 +3761,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(); 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 e35eb07fa3..b78436f1fb 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 publicationWorkspaceItem; private Item publicationItem; private Item personItem1; @@ -103,6 +104,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(); @@ -144,15 +150,13 @@ 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(); - publicationWorkspaceItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection) + publicationWorkspaceItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection2) .withTitle("Publication 1") .withEntityType("Publication") .build(); @@ -239,7 +243,6 @@ public class PatchMetadataIT extends AbstractEntityIntegrationTest { publicationItem = ItemBuilder.createItem(context, collection) .withTitle("Publication 1") - .withEntityType("Publication") .build(); for (String author : authorsOriginalOrder) { 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 0c0ae1153a..eae949caed 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 @@ -218,56 +218,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..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; @@ -5181,8 +5184,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 +5193,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. @@ -5299,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(); + } + } + } 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..7439edb498 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 @@ -60,7 +60,6 @@ public class CsvExportIT extends AbstractControllerIntegrationTest { Item article = ItemBuilder.createItem(context, col1) .withTitle("Article") .withIssueDate("2017-10-17") - .withEntityType("Publication") .build(); AtomicReference idRef = new AtomicReference<>(); @@ -104,14 +103,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 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 7319b453ac..2c6535ea13 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 @@ -44,7 +44,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; } 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; diff --git a/dspace/config/spring/api/external-services.xml b/dspace/config/spring/api/external-services.xml index 5a938568d5..9e28e5d559 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 + none + + + + + Publication + none + + diff --git a/dspace/solr/search/conf/schema.xml b/dspace/solr/search/conf/schema.xml index e16e213135..09eeb173e2 100644 --- a/dspace/solr/search/conf/schema.xml +++ b/dspace/solr/search/conf/schema.xml @@ -263,6 +263,9 @@ + + + @@ -342,5 +345,6 @@ or to add multiple fields to the same field for easier/faster searching. --> +