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 c4f8d288b3..dbe34a2051 100644 --- a/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java @@ -17,11 +17,13 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.MissingResourceException; +import java.util.Set; import java.util.UUID; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; +import org.apache.solr.client.solrj.util.ClientUtils; import org.dspace.app.util.AuthorizeUtil; import org.dspace.authorize.AuthorizeConfiguration; import org.dspace.authorize.AuthorizeException; @@ -40,6 +42,13 @@ import org.dspace.core.Context; import org.dspace.core.I18nUtil; import org.dspace.core.LogManager; import org.dspace.core.service.LicenseService; +import org.dspace.discovery.DiscoverQuery; +import org.dspace.discovery.DiscoverResult; +import org.dspace.discovery.IndexableObject; +import org.dspace.discovery.SearchService; +import org.dspace.discovery.SearchServiceException; +import org.dspace.discovery.indexobject.IndexableCollection; +import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; import org.dspace.eperson.service.GroupService; import org.dspace.eperson.service.SubscribeService; @@ -100,6 +109,9 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i @Autowired(required = true) protected CollectionRoleService collectionRoleService; + @Autowired(required = true) + protected SearchService searchService; + protected CollectionServiceImpl() { super(); } @@ -907,4 +919,66 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i return role; } + @Override + public List findAuthorizedCollectionsInSOLR(String q, Context context, Community community, + int offset, int limit) throws SQLException, SearchServiceException { + + List collections = new ArrayList(); + StringBuilder query = new StringBuilder(); + DiscoverQuery discoverQuery = new DiscoverQuery(); + discoverQuery.setDSpaceObjectFilter(IndexableCollection.TYPE); + discoverQuery.setStart(offset); + discoverQuery.setMaxResults(limit); + DiscoverResult resp = resultSolrQuery(context, query, discoverQuery,community, q); + for (IndexableObject solrCollections : resp.getIndexableObjects()) { + Collection c = ((IndexableCollection) solrCollections).getIndexedObject(); + collections.add(c); + } + return collections; + } + + @Override + public int countAuthorizedCollectionsInSOLR(String q, Context context, Community community) + throws SQLException, SearchServiceException { + + StringBuilder query = new StringBuilder(); + DiscoverQuery discoverQuery = new DiscoverQuery(); + discoverQuery.setDSpaceObjectFilter(IndexableCollection.TYPE); + DiscoverResult resp = resultSolrQuery(context, query, discoverQuery,community,q); + return (int)resp.getTotalSearchResults(); + } + + private DiscoverResult resultSolrQuery(Context context, StringBuilder query, DiscoverQuery discoverQuery, + Community community, String q) throws SQLException, SearchServiceException { + + EPerson currentUser = context.getCurrentUser(); + if (!authorizeService.isAdmin(context)) { + Group anonymousGroup = groupService.findByName(context, Group.ANONYMOUS); + String anonGroupId = ""; + if (anonymousGroup != null) { + anonGroupId = anonymousGroup.getID().toString(); + } + query.append("submit:(g").append(anonGroupId); + if (currentUser != null) { + query.append(" OR e").append(currentUser.getID()); + } + Set groups = groupService.allMemberGroupsSet(context, currentUser); + for (Group group : groups) { + query.append(" OR g").append(group.getID()); + } + query.append(")"); + discoverQuery.addFilterQueries(query.toString()); + } + if (community != null) { + discoverQuery.addFilterQueries("location.comm:" + community.getID().toString()); + } + if (StringUtils.isNotBlank(q)) { + StringBuilder buildQuery = new StringBuilder(); + String escapedQuery = ClientUtils.escapeQueryChars(q); + buildQuery.append(escapedQuery).append(" OR ").append(escapedQuery).append("*"); + discoverQuery.setQuery(buildQuery.toString()); + } + DiscoverResult resp = searchService.search(context, discoverQuery); + return resp; + } } 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 5038aef6d7..1194ac70b0 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 @@ -20,8 +20,10 @@ import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.Item; import org.dspace.core.Context; +import org.dspace.discovery.SearchServiceException; import org.dspace.eperson.Group; + /** * Service interface class for the Collection object. * The implementation of this class is responsible for all business logic calls for the Collection object and is @@ -354,4 +356,34 @@ public interface CollectionService */ Group createDefaultReadGroup(Context context, Collection collection, String typeOfGroupString, int defaultRead) throws SQLException, AuthorizeException; + + /** + * + * @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 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 findAuthorizedCollectionsInSOLR(String q, Context context, Community community, + int offset, int limit) throws SQLException, SearchServiceException; + + /** + * + * @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 + * @return total collections found + * @throws SQLException if something goes wrong + * @throws SearchServiceException if search error + */ + public int countAuthorizedCollectionsInSOLR(String q, Context context, Community community) + throws SQLException, SearchServiceException; } 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 c08bc69ca7..47b66c7933 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,7 +11,6 @@ import java.io.IOException; import java.sql.SQLException; import java.util.LinkedList; import java.util.List; -import java.util.Set; import java.util.SortedMap; import java.util.UUID; import javax.servlet.ServletInputStream; @@ -21,7 +20,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; -import org.apache.solr.client.solrj.util.ClientUtils; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; import org.dspace.app.rest.exception.DSpaceBadRequestException; @@ -56,7 +54,6 @@ import org.dspace.discovery.IndexableObject; import org.dspace.discovery.SearchService; import org.dspace.discovery.SearchServiceException; import org.dspace.discovery.indexobject.IndexableCollection; -import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; import org.dspace.eperson.service.GroupService; import org.dspace.workflow.WorkflowException; @@ -178,70 +175,26 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository collections = new LinkedList(); - DiscoverResult resp = discoverAuthorizedCollections(pageable, q, context, com); - long tot = resp.getTotalSearchResults(); - for (IndexableObject solrCollections : resp.getIndexableObjects()) { - Collection c = ((IndexableCollection) solrCollections).getIndexedObject(); - collections.add(c); - } + List collections = cs.findAuthorizedCollectionsInSOLR(q, context, com, + Math.toIntExact(pageable.getOffset()), + Math.toIntExact(pageable.getOffset() + pageable.getPageSize())); + int tot = cs.countAuthorizedCollectionsInSOLR(q, context, com); return converter.toRestPage(collections, pageable, tot , utils.obtainProjection()); } catch (SQLException | SearchServiceException e) { throw new RuntimeException(e.getMessage(), e); } } - private DiscoverResult discoverAuthorizedCollections(Pageable pageable, String q, Context context, Community com) - throws SQLException, SearchServiceException { - StringBuilder query = new StringBuilder(); - DiscoverQuery discoverQuery = new DiscoverQuery(); - discoverQuery.setDSpaceObjectFilter(IndexableCollection.TYPE); - discoverQuery.setStart(Math.toIntExact(pageable.getOffset())); - discoverQuery.setMaxResults(pageable.getPageSize()); - EPerson currentUser = context.getCurrentUser(); - if (!authorizeService.isAdmin(context)) { - Group anonymousGroup = groupService.findByName(context, Group.ANONYMOUS); - String anonGroupId = ""; - if (anonymousGroup != null) { - anonGroupId = anonymousGroup.getID().toString(); - } - query.append("submit:(g").append(anonGroupId); - if (currentUser != null) { - query.append(" OR e").append(currentUser.getID()); - } - Set groups = groupService.allMemberGroupsSet(context, currentUser); - for (Group group : groups) { - query.append(" OR g").append(group.getID()); - } - query.append(")"); - discoverQuery.addFilterQueries(query.toString()); - } - if (com != null) { - discoverQuery.addFilterQueries("location.comm:" + com.getID().toString()); - } - if (StringUtils.isNotBlank(q)) { - StringBuilder buildQuery = new StringBuilder(); - String escapedQuery = ClientUtils.escapeQueryChars(q); - buildQuery.append(escapedQuery).append(" OR ").append(escapedQuery).append("*"); - discoverQuery.setQuery(buildQuery.toString()); - } - DiscoverResult resp = searchService.search(context, discoverQuery); - return resp; - } - @SearchRestMethod(name = "findAuthorized") public Page findAuthorized(@Parameter(value = "query") String q, Pageable pageable) throws SearchServiceException { try { Context context = obtainContext(); - List collections = new LinkedList(); - DiscoverResult resp = discoverAuthorizedCollections(pageable, q, context, null); - long tot = resp.getTotalSearchResults(); - for (IndexableObject solrCollections : resp.getIndexableObjects()) { - Collection c = ((IndexableCollection) solrCollections).getIndexedObject(); - collections.add(c); - } - return converter.toRestPage(collections, pageable, tot , utils.obtainProjection()); + List collections = cs.findAuthorizedCollectionsInSOLR(q, context, null, + Math.toIntExact(pageable.getOffset()), + Math.toIntExact(pageable.getOffset() + pageable.getPageSize())); + int tot = cs.countAuthorizedCollectionsInSOLR(q, context, null); + return converter.toRestPage(collections, pageable, tot, utils.obtainProjection()); } catch (SQLException e) { throw new RuntimeException(e.getMessage(), e); } diff --git a/dspace/solr/search/conf/schema.xml b/dspace/solr/search/conf/schema.xml index 60920eb5ee..e16e213135 100644 --- a/dspace/solr/search/conf/schema.xml +++ b/dspace/solr/search/conf/schema.xml @@ -254,12 +254,14 @@ + +