Merge pull request #2612 from atmire/DS-4287-indexableobject-refactor

[DS 4287] Refactoring the IndexableObject & SolrServiceImpl
This commit is contained in:
Tim Donohue
2020-01-16 16:21:57 -06:00
committed by GitHub
113 changed files with 3185 additions and 1853 deletions

View File

@@ -50,9 +50,11 @@ import org.dspace.content.service.CollectionService;
import org.dspace.content.service.CommunityService;
import org.dspace.content.service.ItemService;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.discovery.IndexableObject;
import org.dspace.discovery.indexobject.IndexableCollection;
import org.dspace.discovery.indexobject.IndexableCommunity;
import org.dspace.discovery.indexobject.IndexableItem;
import org.dspace.handle.factory.HandleServiceFactory;
import org.dspace.services.ConfigurationService;
import org.dspace.services.factory.DSpaceServicesFactory;
@@ -200,8 +202,8 @@ public class SyndicationFeed {
logoURL = ConfigurationManager.getProperty("webui.feed.logo.url");
} else {
Bitstream logo = null;
if (dso.getType() == Constants.COLLECTION) {
Collection col = (Collection) dso;
if (dso instanceof IndexableCollection) {
Collection col = ((IndexableCollection) dso).getIndexedObject();
defaultTitle = col.getName();
feed.setDescription(collectionService.getMetadata(col, "short_description"));
logo = col.getLogo();
@@ -210,8 +212,8 @@ public class SyndicationFeed {
podcastFeed = true;
}
objectURL = resolveURL(request, col);
} else if (dso.getType() == Constants.COMMUNITY) {
Community comm = (Community) dso;
} else if (dso instanceof IndexableCommunity) {
Community comm = ((IndexableCommunity) dso).getIndexedObject();
defaultTitle = comm.getName();
feed.setDescription(communityService.getMetadata(comm, "short_description"));
logo = comm.getLogo();
@@ -251,10 +253,10 @@ public class SyndicationFeed {
if (items != null) {
List<SyndEntry> entries = new ArrayList<SyndEntry>();
for (IndexableObject idxObj : items) {
if (idxObj.getType() != Constants.ITEM) {
if (!(idxObj instanceof IndexableItem)) {
continue;
}
Item item = (Item) idxObj;
Item item = ((IndexableItem) idxObj).getIndexedObject();
boolean hasDate = false;
SyndEntry entry = new SyndEntryImpl();
entries.add(entry);

View File

@@ -12,6 +12,8 @@ import org.dspace.content.Community;
import org.dspace.content.DSpaceObject;
import org.dspace.core.Context;
import org.dspace.discovery.IndexableObject;
import org.dspace.discovery.indexobject.IndexableCollection;
import org.dspace.discovery.indexobject.IndexableCommunity;
import org.dspace.sort.SortException;
import org.dspace.sort.SortOption;
@@ -136,10 +138,10 @@ public class BrowserScope {
*/
public void setBrowseContainer(IndexableObject dso)
throws BrowseException {
if (dso instanceof Collection) {
this.collection = (Collection) dso;
} else if (dso instanceof Community) {
this.community = (Community) dso;
if (dso instanceof IndexableCollection) {
this.collection = ((IndexableCollection) dso).getIndexedObject();
} else if (dso instanceof IndexableCommunity) {
this.community = ((IndexableCommunity) dso).getIndexedObject();
} else {
throw new BrowseException("The container must be a community or a collection");
}

View File

@@ -23,6 +23,7 @@ import org.dspace.discovery.DiscoverResult.FacetResult;
import org.dspace.discovery.SearchService;
import org.dspace.discovery.SearchServiceException;
import org.dspace.discovery.configuration.DiscoveryConfigurationParameters;
import org.dspace.discovery.indexobject.IndexableItem;
import org.dspace.services.factory.DSpaceServicesFactory;
/**
@@ -122,7 +123,7 @@ public class ItemCountDAOSolr implements ItemCountDAO {
query.addFacetField(new DiscoverFacetField("location.coll",
DiscoveryConfigurationParameters.TYPE_STANDARD, -1,
DiscoveryConfigurationParameters.SORT.COUNT));
query.addFilterQueries("search.resourcetype:2"); // count only items
query.addFilterQueries("search.resourcetype:" + IndexableItem.TYPE); // count only items
query.addFilterQueries("NOT(discoverable:false)"); // only discoverable
query.setMaxResults(0);

View File

@@ -20,7 +20,6 @@ import org.apache.logging.log4j.Logger;
import org.dspace.authorize.factory.AuthorizeServiceFactory;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.content.Item;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.discovery.DiscoverFacetField;
import org.dspace.discovery.DiscoverQuery;
@@ -32,6 +31,7 @@ import org.dspace.discovery.IndexableObject;
import org.dspace.discovery.SearchService;
import org.dspace.discovery.SearchServiceException;
import org.dspace.discovery.configuration.DiscoveryConfigurationParameters;
import org.dspace.discovery.indexobject.IndexableItem;
import org.dspace.services.factory.DSpaceServicesFactory;
/**
@@ -207,7 +207,7 @@ public class SolrBrowseDAO implements BrowseDAO {
}
// filter on item to be sure to don't include any other object
// indexed in the Discovery Search core
query.addFilterQueries("search.resourcetype:" + Constants.ITEM);
query.addFilterQueries("search.resourcetype:" + IndexableItem.TYPE);
if (orderField != null) {
query.setSortField("bi_" + orderField + "_sort",
ascending ? SORT_ORDER.asc : SORT_ORDER.desc);
@@ -297,10 +297,10 @@ public class SolrBrowseDAO implements BrowseDAO {
DiscoverResult resp = getSolrResponse();
List<Item> bitems = new ArrayList<>();
for (IndexableObject<UUID> solrDoc : resp.getIndexableObjects()) {
for (IndexableObject solrDoc : resp.getIndexableObjects()) {
// FIXME introduce project, don't retrieve Item immediately when
// processing the query...
Item item = (Item) solrDoc;
Item item = ((IndexableItem) solrDoc).getIndexedObject();
bitems.add(item);
}
return bitems;
@@ -311,7 +311,7 @@ public class SolrBrowseDAO implements BrowseDAO {
throws BrowseException {
DiscoverQuery query = new DiscoverQuery();
query.setQuery("search.resourceid:" + itemID
+ " AND search.resourcetype:" + Constants.ITEM);
+ " AND search.resourcetype:" + IndexableItem.TYPE);
query.setMaxResults(1);
DiscoverResult resp = null;
try {
@@ -334,7 +334,7 @@ public class SolrBrowseDAO implements BrowseDAO {
addLocationScopeFilter(query);
addStatusFilter(query);
query.setMaxResults(0);
query.addFilterQueries("search.resourcetype:" + Constants.ITEM);
query.addFilterQueries("search.resourcetype:" + IndexableItem.TYPE);
// We need to take into account the fact that we may be in a subset of the items
if (authority != null) {

View File

@@ -12,7 +12,6 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import javax.persistence.Cacheable;
import javax.persistence.CascadeType;
@@ -32,7 +31,6 @@ import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.CollectionService;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.discovery.IndexableObject;
import org.dspace.eperson.Group;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.proxy.HibernateProxyHelper;
@@ -55,7 +53,7 @@ import org.hibernate.proxy.HibernateProxyHelper;
@Table(name = "collection")
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, include = "non-lazy")
public class Collection extends DSpaceObject implements DSpaceObjectLegacySupport, IndexableObject<UUID> {
public class Collection extends DSpaceObject implements DSpaceObjectLegacySupport {
@Column(name = "collection_id", insertable = false, updatable = false)
private Integer legacyId;
@@ -331,9 +329,4 @@ public class Collection extends DSpaceObject implements DSpaceObjectLegacySuppor
return collectionService;
}
@Override
public String getTypeText() {
return Constants.typeText[Constants.COLLECTION];
}
}

View File

@@ -277,15 +277,6 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
return collectionDAO.findByID(context, Collection.class, id);
}
@Override
/**
* This method is an alias of the find method needed to avoid ambiguity between the IndexableObjectService interface
* and the DSpaceObjectService interface
*/
public Collection findIndexableObject(Context context, UUID id) throws SQLException {
return collectionDAO.findByID(context, Collection.class, id);
}
@Override
public void setMetadata(Context context, Collection collection, String field, String value)
throws MissingResourceException, SQLException {
@@ -794,15 +785,6 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
return Constants.COLLECTION;
}
@Override
/**
* This method is an alias of the getSupportsTypeConstant method needed to avoid ambiguity between the
* IndexableObjectService interface and the DSpaceObjectService interface
*/
public int getSupportsIndexableObjectTypeConstant() {
return getSupportsTypeConstant();
}
@Override
public List<Collection> findAuthorized(Context context, Community community, int actionID) throws SQLException {
List<Collection> myResults = new ArrayList<>();

View File

@@ -11,7 +11,6 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import javax.persistence.Cacheable;
import javax.persistence.CascadeType;
@@ -32,7 +31,6 @@ import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.CommunityService;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.discovery.IndexableObject;
import org.dspace.eperson.Group;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.proxy.HibernateProxyHelper;
@@ -51,7 +49,7 @@ import org.hibernate.proxy.HibernateProxyHelper;
@Table(name = "community")
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, include = "non-lazy")
public class Community extends DSpaceObject implements DSpaceObjectLegacySupport, IndexableObject<UUID> {
public class Community extends DSpaceObject implements DSpaceObjectLegacySupport {
/**
* log4j category
*/
@@ -254,11 +252,6 @@ public class Community extends DSpaceObject implements DSpaceObjectLegacySupport
return Constants.COMMUNITY;
}
@Override
public String getTypeText() {
return Constants.typeText[Constants.COMMUNITY];
}
@Override
public String getName() {
String value = getCommunityService()

View File

@@ -137,15 +137,6 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
return communityDAO.findByID(context, Community.class, id);
}
@Override
/**
* This method is an alias of the find method needed to avoid ambiguity between the IndexableObjectService interface
* and the DSpaceObjectService interface
*/
public Community findIndexableObject(Context context, UUID id) throws SQLException {
return find(context, id);
}
@Override
public List<Community> findAll(Context context) throws SQLException {
MetadataField sortField = metadataFieldService.findByElement(context, MetadataSchemaEnum.DC.getName(),
@@ -520,15 +511,6 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
return Constants.COMMUNITY;
}
@Override
/**
* This method is an alias of the getSupportsTypeConstant method needed to avoid ambiguity between the
* IndexableObjectService interface and the DSpaceObjectService interface
*/
public int getSupportsIndexableObjectTypeConstant() {
return getSupportsTypeConstant();
}
/**
* Internal method to remove the community and all its children from the
* database, and perform any pre/post-cleanup

View File

@@ -7,10 +7,9 @@
*/
package org.dspace.content;
import java.io.Serializable;
import java.sql.SQLException;
import org.dspace.discovery.IndexableObject;
import org.dspace.core.ReloadableEntity;
import org.dspace.eperson.EPerson;
/**
@@ -20,13 +19,13 @@ import org.dspace.eperson.EPerson;
* @author Robert Tansley
* @version $Revision$
*/
public interface InProgressSubmission<ID extends Serializable> extends IndexableObject<ID> {
public interface InProgressSubmission extends ReloadableEntity<Integer> {
/**
* Get the internal ID of this submission
*
* @return the internal identifier
*/
ID getID();
Integer getID();
/**
* Get the incomplete item object
@@ -48,7 +47,7 @@ public interface InProgressSubmission<ID extends Serializable> extends Indexable
* @return the submitting e-person
* @throws SQLException if database error
*/
EPerson getSubmitter() throws SQLException;
EPerson getSubmitter();
/**
* Find out if the submission has (or is intended to have) more than one

View File

@@ -13,7 +13,6 @@ import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@@ -35,7 +34,6 @@ import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.ItemService;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.discovery.IndexableObject;
import org.dspace.eperson.EPerson;
import org.hibernate.proxy.HibernateProxyHelper;
@@ -55,7 +53,7 @@ import org.hibernate.proxy.HibernateProxyHelper;
*/
@Entity
@Table(name = "item")
public class Item extends DSpaceObject implements DSpaceObjectLegacySupport, IndexableObject<UUID> {
public class Item extends DSpaceObject implements DSpaceObjectLegacySupport {
/**
* log4j logger
@@ -376,10 +374,4 @@ public class Item extends DSpaceObject implements DSpaceObjectLegacySupport, Ind
}
return itemService;
}
@Override
public String getTypeText() {
return getItemService().getTypeText(this);
}
}

View File

@@ -172,15 +172,6 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
return item;
}
@Override
/**
* This method is an alias of the find method needed to avoid ambiguity between the IndexableObjectService interface
* and the DSpaceObjectService interface
*/
public Item findIndexableObject(Context context, UUID id) throws SQLException {
return find(context, id);
}
@Override
public Item create(Context context, WorkspaceItem workspaceItem) throws SQLException, AuthorizeException {
if (workspaceItem.getItem() != null) {
@@ -677,15 +668,6 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
return Constants.ITEM;
}
@Override
/**
* This method is an alias of the getSupportsTypeConstant method needed to avoid ambiguity between the
* IndexableObjectService interface and the DSpaceObjectService interface
*/
public int getSupportsIndexableObjectTypeConstant() {
return getSupportsTypeConstant();
}
protected void rawDelete(Context context, Item item) throws AuthorizeException, SQLException, IOException {
authorizeService.authorizeAction(context, item, Constants.REMOVE);

View File

@@ -8,7 +8,6 @@
package org.dspace.content;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@@ -27,10 +26,7 @@ import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.ReloadableEntity;
import org.dspace.discovery.IndexableObject;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.workflow.WorkflowItem;
@@ -45,7 +41,7 @@ import org.hibernate.proxy.HibernateProxyHelper;
@Entity
@Table(name = "workspaceitem")
public class WorkspaceItem
implements InProgressSubmission<Integer>, Serializable, ReloadableEntity<Integer>, IndexableObject<Integer> {
implements InProgressSubmission, Serializable {
@Id
@Column(name = "workspace_item_id", unique = true, nullable = false)
@@ -197,7 +193,7 @@ public class WorkspaceItem
}
@Override
public EPerson getSubmitter() throws SQLException {
public EPerson getSubmitter() {
return item.getSubmitter();
}
@@ -242,10 +238,4 @@ public class WorkspaceItem
void addSupervisorGroup(Group group) {
supervisorGroups.add(group);
}
@Override
public int getType() {
return Constants.WORKSPACEITEM;
}
}

View File

@@ -60,11 +60,6 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService {
}
@Override
public int getSupportsIndexableObjectTypeConstant() {
return Constants.WORKSPACEITEM;
}
@Override
public WorkspaceItem find(Context context, int id) throws SQLException {
WorkspaceItem workspaceItem = workspaceItemDAO.findByID(context, WorkspaceItem.class, id);
@@ -83,14 +78,6 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService {
return workspaceItem;
}
@Override
public WorkspaceItem findIndexableObject(Context context, Integer id) throws SQLException {
if (id != null) {
return find(context, id);
}
return null;
}
@Override
public WorkspaceItem create(Context context, Collection collection, boolean template)
throws AuthorizeException, SQLException {

View File

@@ -7,7 +7,6 @@
*/
package org.dspace.content.factory;
import java.io.Serializable;
import java.util.List;
import org.dspace.content.DSpaceObject;
@@ -24,7 +23,6 @@ import org.dspace.content.service.DSpaceObjectService;
import org.dspace.content.service.EntityService;
import org.dspace.content.service.EntityTypeService;
import org.dspace.content.service.InProgressSubmissionService;
import org.dspace.content.service.IndexableObjectService;
import org.dspace.content.service.InstallItemService;
import org.dspace.content.service.ItemService;
import org.dspace.content.service.MetadataFieldService;
@@ -35,7 +33,6 @@ import org.dspace.content.service.RelationshipTypeService;
import org.dspace.content.service.SiteService;
import org.dspace.content.service.SupervisedItemService;
import org.dspace.content.service.WorkspaceItemService;
import org.dspace.discovery.IndexableObject;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.workflow.factory.WorkflowServiceFactory;
@@ -47,13 +44,6 @@ import org.dspace.workflow.factory.WorkflowServiceFactory;
*/
public abstract class ContentServiceFactory {
/**
* Return the list of all the available implementations of the IndexableObjectService interface
*
* @return the list of IndexableObjectService
*/
public abstract List<IndexableObjectService> getIndexableObjectServices();
public abstract List<DSpaceObjectService<? extends DSpaceObject>> getDSpaceObjectServices();
public abstract List<DSpaceObjectLegacySupportService<? extends DSpaceObject>>
@@ -142,18 +132,6 @@ public abstract class ContentServiceFactory {
throw new UnsupportedOperationException("Unknown DSpace type: " + type);
}
@SuppressWarnings("unchecked")
public <T extends IndexableObject<PK>, PK extends Serializable> IndexableObjectService<T, PK>
getIndexableObjectService(int type) {
for (int i = 0; i < getIndexableObjectServices().size(); i++) {
IndexableObjectService objectService = getIndexableObjectServices().get(i);
if (objectService.getSupportsIndexableObjectTypeConstant() == type) {
return (IndexableObjectService<T, PK>) objectService;
}
}
throw new UnsupportedOperationException("Unknown Findable Object type: " + type);
}
public DSpaceObjectLegacySupportService<? extends DSpaceObject> getDSpaceLegacyObjectService(int type) {
for (int i = 0; i < getDSpaceObjectLegacySupportServices().size(); i++) {
DSpaceObjectLegacySupportService<? extends DSpaceObject> objectLegacySupportService =

View File

@@ -20,7 +20,6 @@ import org.dspace.content.service.DSpaceObjectLegacySupportService;
import org.dspace.content.service.DSpaceObjectService;
import org.dspace.content.service.EntityService;
import org.dspace.content.service.EntityTypeService;
import org.dspace.content.service.IndexableObjectService;
import org.dspace.content.service.InstallItemService;
import org.dspace.content.service.ItemService;
import org.dspace.content.service.MetadataFieldService;
@@ -31,7 +30,6 @@ import org.dspace.content.service.RelationshipTypeService;
import org.dspace.content.service.SiteService;
import org.dspace.content.service.SupervisedItemService;
import org.dspace.content.service.WorkspaceItemService;
import org.dspace.utils.DSpace;
import org.springframework.beans.factory.annotation.Autowired;
/**
@@ -85,11 +83,6 @@ public class ContentServiceFactoryImpl extends ContentServiceFactory {
@Autowired(required = true)
private EntityService entityService;
@Override
public List<IndexableObjectService> getIndexableObjectServices() {
return new DSpace().getServiceManager().getServicesByType(IndexableObjectService.class);
}
@Override
public List<DSpaceObjectService<? extends DSpaceObject>> getDSpaceObjectServices() {
return dSpaceObjectServices;

View File

@@ -13,7 +13,6 @@ import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.UUID;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bitstream;
@@ -31,8 +30,7 @@ import org.dspace.eperson.Group;
* @author kevinvandevelde at atmire.com
*/
public interface CollectionService
extends DSpaceObjectService<Collection>, DSpaceObjectLegacySupportService<Collection>,
IndexableObjectService<Collection, UUID> {
extends DSpaceObjectService<Collection>, DSpaceObjectLegacySupportService<Collection> {
/**
* Create a new collection with a new ID.

View File

@@ -12,7 +12,6 @@ import java.io.InputStream;
import java.sql.SQLException;
import java.util.List;
import java.util.MissingResourceException;
import java.util.UUID;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bitstream;
@@ -28,8 +27,7 @@ import org.dspace.eperson.Group;
*
* @author kevinvandevelde at atmire.com
*/
public interface CommunityService extends DSpaceObjectService<Community>, DSpaceObjectLegacySupportService<Community>,
IndexableObjectService<Community, UUID> {
public interface CommunityService extends DSpaceObjectService<Community>, DSpaceObjectLegacySupportService<Community> {
/**

View File

@@ -7,7 +7,6 @@
*/
package org.dspace.content.service;
import java.io.Serializable;
import java.sql.SQLException;
import org.dspace.app.util.DCInputsReaderException;
@@ -25,8 +24,7 @@ import org.dspace.core.Context;
* @param <T> class type
* @author kevinvandevelde at atmire.com
*/
public interface InProgressSubmissionService<T extends InProgressSubmission<ID>, ID extends Serializable>
extends IndexableObjectService<T, ID> {
public interface InProgressSubmissionService<T extends InProgressSubmission> {
/**
* Deletes submission wrapper, doesn't delete item contents

View File

@@ -1,44 +0,0 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.content.service;
import java.io.Serializable;
import java.sql.SQLException;
import org.dspace.core.Context;
import org.dspace.discovery.IndexableObject;
/**
* Base Service interface class for any IndexableObject. The name of the methods contains IndexableObject to avoid
* ambiguity reference as some implementation supports both this interface than the DSpaceObectService interface
*
* @param <T>
* class type of the indexable object
* @param <PK>
* class type of the primary key
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
public interface IndexableObjectService<T extends IndexableObject<PK>, PK extends Serializable> {
/**
* Generic find for when the precise type of an IndexableObject is not known
*
* @param context - the context
* @param id - id within table of type'd indexable objects
* @return the indexable object found, or null if it does not exist.
* @throws SQLException only upon failure accessing the database.
*/
public T findIndexableObject(Context context, PK id) throws SQLException;
/**
* Returns the Constants which this service supports
*
* @return a org.dspace.core.Constants that represents a IndexableObject type
*/
public int getSupportsIndexableObjectTypeConstant();
}

View File

@@ -38,7 +38,7 @@ import org.dspace.eperson.Group;
* @author kevinvandevelde at atmire.com
*/
public interface ItemService
extends DSpaceObjectService<Item>, DSpaceObjectLegacySupportService<Item>, IndexableObjectService<Item, UUID> {
extends DSpaceObjectService<Item>, DSpaceObjectLegacySupportService<Item> {
public Thumbnail getThumbnail(Context context, Item item, boolean requireOriginal) throws SQLException;

View File

@@ -27,7 +27,7 @@ import org.dspace.workflow.WorkflowItem;
*
* @author kevinvandevelde at atmire.com
*/
public interface WorkspaceItemService extends InProgressSubmissionService<WorkspaceItem, Integer> {
public interface WorkspaceItemService extends InProgressSubmissionService<WorkspaceItem> {
/**
* Get a workspace item from the database. The item, collection and

View File

@@ -55,31 +55,11 @@ public class Constants {
*/
public static final int EPERSON = 7;
/**
* Type of workspace item objects
*/
public static final int WORKSPACEITEM = 8;
/**
* Type of workflow item objects
*/
public static final int WORKFLOWITEM = 9;
/**
* Type of pool task objects
*/
public static final int POOLTASK = 10;
/**
* Type of claimed task objects
*/
public static final int CLAIMEDTASK = 11;
/**
* lets you look up type names from the type IDs
*/
public static final String[] typeText = { "BITSTREAM", "BUNDLE", "ITEM", "COLLECTION", "COMMUNITY", "SITE", "GROUP",
"EPERSON", "WORKSPACEITEM", "WORKFLOWITEM", "POOLTASK", "CLAIMEDTASK" };
"EPERSON"};
/**
* Special Bundle and Bitstream Names:

View File

@@ -31,7 +31,7 @@ public class DiscoverQuery {
**/
private String query;
private List<String> filterQueries;
private int DSpaceObjectFilter = -1;
private String DSpaceObjectFilter = null;
private List<String> fieldPresentQueries;
private boolean spellCheck;
@@ -120,7 +120,7 @@ public class DiscoverQuery {
*
* @param DSpaceObjectFilter the DSpace object filer
*/
public void setDSpaceObjectFilter(int DSpaceObjectFilter) {
public void setDSpaceObjectFilter(String DSpaceObjectFilter) {
this.DSpaceObjectFilter = DSpaceObjectFilter;
}
@@ -130,7 +130,7 @@ public class DiscoverQuery {
*
* @return the DSpace object filer
*/
public int getDSpaceObjectFilter() {
public String getDSpaceObjectFilter() {
return DSpaceObjectFilter;
}

View File

@@ -243,7 +243,7 @@ public class DiscoverResult {
String dsoString = SearchDocument.getIndexableObjectStringRepresentation(idxObj);
List<SearchDocument> result = searchDocuments.get(dsoString);
if (result == null) {
return new ArrayList<SearchDocument>();
return new ArrayList<>();
} else {
return result;
}

View File

@@ -10,6 +10,7 @@ package org.dspace.discovery;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Optional;
import java.util.UUID;
import org.apache.commons.cli.CommandLine;
@@ -17,11 +18,16 @@ import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.DSpaceObject;
import org.dspace.content.Item;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.ItemService;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.discovery.indexobject.IndexableCollection;
import org.dspace.discovery.indexobject.IndexableCommunity;
import org.dspace.discovery.indexobject.IndexableItem;
import org.dspace.discovery.indexobject.factory.IndexFactory;
import org.dspace.discovery.indexobject.factory.IndexObjectFactoryFactory;
import org.dspace.handle.factory.HandleServiceFactory;
import org.dspace.scripts.DSpaceRunnable;
import org.springframework.beans.factory.annotation.Autowired;
@@ -79,28 +85,42 @@ public class IndexClient extends DSpaceRunnable {
} catch (Exception e) {
// nothing to do, it should be an handle
}
IndexableObject dso = null;
Optional<IndexableObject> indexableObject = Optional.empty();
if (uuid != null) {
dso = ContentServiceFactory.getInstance().getItemService().find(context, uuid);
if (dso == null) {
final Item item = ContentServiceFactory.getInstance().getItemService().find(context, uuid);
if (item != null) {
indexableObject = Optional.of(new IndexableItem(item));
} else {
// it could be a community
dso = ContentServiceFactory.getInstance().getCommunityService().find(context, uuid);
if (dso == null) {
final Community community = ContentServiceFactory.getInstance().
getCommunityService().find(context, uuid);
if (community != null) {
indexableObject = Optional.of(new IndexableCommunity(community));
} else {
// it could be a collection
dso = ContentServiceFactory.getInstance().getCollectionService().find(context, uuid);
final Collection collection = ContentServiceFactory.getInstance().
getCollectionService().find(context, uuid);
if (collection != null) {
indexableObject = Optional.of(new IndexableCollection(collection));
}
}
}
} else {
dso = (IndexableObject) HandleServiceFactory.getInstance()
.getHandleService().resolveToObject(context, param);
final DSpaceObject dso = HandleServiceFactory.getInstance()
.getHandleService().resolveToObject(context, param);
if (dso != null) {
final IndexFactory indexableObjectService = IndexObjectFactoryFactory.getInstance().
getIndexFactoryByType(String.valueOf(dso.getType()));
indexableObject = indexableObjectService.findIndexableObject(context, dso.getID().toString());
}
}
if (dso == null) {
if (!indexableObject.isPresent()) {
throw new IllegalArgumentException("Cannot resolve " + param + " to a DSpace object");
}
handler.logInfo("Indexing " + param + " force " + commandLine.hasOption("f"));
final long startTimeMillis = System.currentTimeMillis();
final long count = indexAll(indexer, ContentServiceFactory.getInstance().getItemService(), context,
dso);
final long count = indexAll(indexer, ContentServiceFactory.getInstance().
getItemService(), context, indexableObject.get());
final long seconds = (System.currentTimeMillis() - startTimeMillis) / 1000;
handler.logInfo("Indexed " + count + " object" + (count > 1 ? "s" : "") + " in " + seconds + " seconds");
} else if (indexClientOptions == IndexClientOptions.UPDATE ||
@@ -163,11 +183,11 @@ public class IndexClient extends DSpaceRunnable {
indexingService.indexContent(context, dso, true, true);
count++;
if (dso.getType() == Constants.COMMUNITY) {
if (dso.getIndexedObject() instanceof Community) {
final Community community = (Community) dso;
final String communityHandle = community.getHandle();
for (final Community subcommunity : community.getSubcommunities()) {
count += indexAll(indexingService, itemService, context, subcommunity);
count += indexAll(indexingService, itemService, context, new IndexableCommunity(subcommunity));
//To prevent memory issues, discard an object from the cache after processing
context.uncacheEntity(subcommunity);
}
@@ -176,13 +196,13 @@ public class IndexClient extends DSpaceRunnable {
communityHandle);
for (final Collection collection : reloadedCommunity.getCollections()) {
count++;
indexingService.indexContent(context, collection, true, true);
indexingService.indexContent(context, new IndexableCollection(collection), true, true);
count += indexItems(indexingService, itemService, context, collection);
//To prevent memory issues, discard an object from the cache after processing
context.uncacheEntity(collection);
}
} else if (dso.getType() == Constants.COLLECTION) {
count += indexItems(indexingService, itemService, context, (Collection) dso);
} else if (dso instanceof IndexableCollection) {
count += indexItems(indexingService, itemService, context, (Collection) dso.getIndexedObject());
}
return count;
@@ -209,7 +229,7 @@ public class IndexClient extends DSpaceRunnable {
final Iterator<Item> itemIterator = itemService.findByCollection(context, collection);
while (itemIterator.hasNext()) {
Item item = itemIterator.next();
indexingService.indexContent(context, item, true, false);
indexingService.indexContent(context, new IndexableItem(item), true, false);
count++;
//To prevent memory issues, discard an object from the cache after processing
context.uncacheEntity(item);

View File

@@ -15,6 +15,7 @@ import org.dspace.content.Bundle;
import org.dspace.content.DSpaceObject;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.discovery.indexobject.factory.IndexObjectFactoryFactory;
import org.dspace.event.Consumer;
import org.dspace.event.Event;
import org.dspace.services.factory.DSpaceServicesFactory;
@@ -42,6 +43,8 @@ public class IndexEventConsumer implements Consumer {
.getServiceByName(IndexingService.class.getName(),
IndexingService.class);
IndexObjectFactoryFactory indexObjectServiceFactory = IndexObjectFactoryFactory.getInstance();
@Override
public void initialize() throws Exception {
@@ -58,8 +61,8 @@ public class IndexEventConsumer implements Consumer {
public void consume(Context ctx, Event event) throws Exception {
if (objectsToUpdate == null) {
objectsToUpdate = new HashSet<IndexableObject>();
uniqueIdsToDelete = new HashSet<String>();
objectsToUpdate = new HashSet<>();
uniqueIdsToDelete = new HashSet<>();
}
int st = event.getSubjectType();
@@ -103,11 +106,11 @@ public class IndexEventConsumer implements Consumer {
if (subject == null) {
log.warn(event.getEventTypeAsString() + " event, could not get object for "
+ event.getSubjectTypeAsString() + " id="
+ String.valueOf(event.getSubjectID())
+ event.getSubjectID()
+ ", perhaps it has been deleted.");
} else {
log.debug("consume() adding event to update queue: " + event.toString());
objectsToUpdate.add((IndexableObject)subject);
objectsToUpdate.addAll(indexObjectServiceFactory.getIndexableObjects(ctx, subject));
}
break;
@@ -116,11 +119,11 @@ public class IndexEventConsumer implements Consumer {
if (object == null) {
log.warn(event.getEventTypeAsString() + " event, could not get object for "
+ event.getObjectTypeAsString() + " id="
+ String.valueOf(event.getObjectID())
+ event.getObjectID()
+ ", perhaps it has been deleted.");
} else {
log.debug("consume() adding event to update queue: " + event.toString());
objectsToUpdate.add((IndexableObject)object);
objectsToUpdate.addAll(indexObjectServiceFactory.getIndexableObjects(ctx, subject));
}
break;
@@ -159,14 +162,14 @@ public class IndexEventConsumer implements Consumer {
* allow the search indexer to make
* decisions on indexing and/or removal
*/
iu = ctx.reloadEntity(iu);
iu.setIndexedObject(ctx.reloadEntity(iu.getIndexedObject())); ;
String uniqueIndexID = iu.getUniqueIndexID();
if (uniqueIndexID != null && !uniqueIdsToDelete.contains(uniqueIndexID)) {
try {
indexer.indexContent(ctx, iu, true, true);
log.debug("Indexed "
+ Constants.typeText[iu.getType()]
+ ", id=" + String.valueOf(iu.getID())
+ iu.getTypeText()
+ ", id=" + iu.getID()
+ ", unique_id=" + uniqueIndexID);
} catch (Exception e) {
log.error("Failed while indexing object: ", e);

View File

@@ -8,6 +8,7 @@
package org.dspace.discovery;
import java.io.Serializable;
import java.util.Date;
import org.dspace.core.Constants;
import org.dspace.core.ReloadableEntity;
@@ -20,13 +21,31 @@ import org.dspace.core.ReloadableEntity;
* @param <PK>
* the Class of the primary key
*/
public interface IndexableObject<PK extends Serializable> extends ReloadableEntity<PK> {
public interface IndexableObject<T extends ReloadableEntity, PK extends Serializable> {
/**
*
* @return the integer constant representing the Entity Type, @see {@link Constants}
* @return the string constant representing the Entity Type, @see {@link Constants}
*/
public int getType();
String getType();
/**
* Return the identifier of this indexableObject, this will be the identifier of the object in the database
* @return for a DSpaceObject a uuid will be returned, for a tasks or workflow items an integer will be returned
*/
PK getID();
/**
* Get the entity that is linked to this indexable object
* @return a database entity
*/
T getIndexedObject();
/**
* Set the entity that is linked to this indexable object
* @param object the database entity
*/
void setIndexedObject(T object);
/**
*
@@ -37,11 +56,16 @@ public interface IndexableObject<PK extends Serializable> extends ReloadableEnti
}
/**
*
*
* @return a textual alias of the Entity Type @see {@link #getType()}
*/
default public String getTypeText() {
return Constants.typeText[getType()];
};
String getTypeText();
/**
* Return the last modified date of an of an object, or if no modification dates are stored, return NUll
* @return the last modified date
*/
default Date getLastModified() {
return null;
}
}

View File

@@ -51,14 +51,11 @@ public interface IndexingService {
void updateIndex(Context context, boolean force);
void updateIndex(Context context, boolean force, int type);
void updateIndex(Context context, boolean force, String type);
void cleanIndex(boolean force) throws IOException,
SQLException, SearchServiceException;
void cleanIndex(boolean force, int type) throws IOException,
SQLException, SearchServiceException;
void commit() throws SearchServiceException;
void optimize() throws SearchServiceException;

View File

@@ -32,6 +32,15 @@ import org.dspace.workflow.WorkflowItem;
* @author Ben Bosman (ben at atmire dot com)
*/
public class SearchUtils {
public static final String AUTHORITY_SEPARATOR = "###";
public static final String LAST_INDEXED_FIELD = "SolrIndexer.lastIndexed";
public static final String RESOURCE_UNIQUE_ID = "search.uniqueid";
public static final String RESOURCE_TYPE_FIELD = "search.resourcetype";
public static final String RESOURCE_ID_FIELD = "search.resourceid";
public static final String NAMED_RESOURCE_TYPE = "namedresourcetype";
public static final String FILTER_SEPARATOR = "\n|||\n";
/**
* Cached search service
**/
@@ -161,5 +170,4 @@ public class SearchUtils {
DiscoveryConfiguration configurationExtra = getDiscoveryConfigurationByName(confName);
result.add(configurationExtra);
}
}

View File

@@ -0,0 +1,87 @@
/**
* 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.discovery;
import java.io.IOException;
import org.apache.commons.validator.routines.UrlValidator;
import org.apache.log4j.Logger;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.dspace.discovery.indexobject.IndexableItem;
import org.dspace.services.ConfigurationService;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.storage.rdbms.DatabaseUtils;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Bean containing the SolrClient for the search core
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class SolrSearchCore {
private final Logger log = Logger.getLogger(SolrSearchCore.class);
@Autowired
protected IndexingService indexingService;
@Autowired
protected ConfigurationService configurationService;
/**
* SolrServer for processing indexing events.
*/
protected SolrClient solr = null;
public SolrClient getSolr() {
if (solr == null) {
initSolr();
}
return solr;
}
/**
* Initialize the solr search core
*/
protected void initSolr() {
if (solr == null) {
String solrService = DSpaceServicesFactory.getInstance().getConfigurationService()
.getProperty("discovery.search.server");
UrlValidator urlValidator = new UrlValidator(UrlValidator.ALLOW_LOCAL_URLS);
if (urlValidator.isValid(solrService) || configurationService
.getBooleanProperty("discovery.solr.url.validation.enabled", true)) {
try {
log.debug("Solr URL: " + solrService);
HttpSolrClient solrServer = new HttpSolrClient.Builder(solrService).build();
solrServer.setBaseURL(solrService);
solrServer.setUseMultiPartPost(true);
// Dummy/test query to search for Item (type=2) of ID=1
SolrQuery solrQuery = new SolrQuery()
.setQuery(SearchUtils.RESOURCE_TYPE_FIELD + ":" + IndexableItem.TYPE +
" AND " + SearchUtils.RESOURCE_ID_FIELD + ":1");
// Only return obj identifier fields in result doc
solrQuery.setFields(SearchUtils.RESOURCE_TYPE_FIELD, SearchUtils.RESOURCE_ID_FIELD);
solrServer.query(solrQuery, SolrRequest.METHOD.POST);
// As long as Solr initialized, check with DatabaseUtils to see
// if a reindex is in order. If so, reindex everything
DatabaseUtils.checkReindexDiscovery(indexingService);
solr = solrServer;
} catch (SolrServerException | IOException e) {
log.error("Error while initializing solr server", e);
}
} else {
log.error("Error while initializing solr, invalid url: " + solrService);
}
}
}
}

View File

@@ -14,6 +14,7 @@ import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.Item;
import org.dspace.core.Context;
import org.dspace.discovery.indexobject.IndexableItem;
/**
* This plugin adds three fields to the solr index to make a facet with/without
@@ -29,9 +30,9 @@ import org.dspace.core.Context;
public class SolrServiceContentInOriginalBundleFilterPlugin implements SolrServiceIndexPlugin {
@Override
public void additionalIndex(Context context, IndexableObject dso, SolrInputDocument document) {
if (dso instanceof Item) {
Item item = (Item) dso;
public void additionalIndex(Context context, IndexableObject indexableObject, SolrInputDocument document) {
if (indexableObject instanceof IndexableItem) {
Item item = ((IndexableItem) indexableObject).getIndexedObject();
boolean hasOriginalBundleWithContent = hasOriginalBundleWithContent(item);
// _keyword and _filter because

View File

@@ -14,6 +14,7 @@ import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.Item;
import org.dspace.core.Context;
import org.dspace.discovery.indexobject.IndexableItem;
/**
* <p>
@@ -40,9 +41,9 @@ public class SolrServiceFileInfoPlugin implements SolrServiceIndexPlugin {
private static final String SOLR_FIELD_NAME_FOR_DESCRIPTIONS = "original_bundle_descriptions";
@Override
public void additionalIndex(Context context, IndexableObject dso, SolrInputDocument document) {
if (dso instanceof Item) {
Item item = (Item) dso;
public void additionalIndex(Context context, IndexableObject indexableObject, SolrInputDocument document) {
if (indexableObject instanceof IndexableItem) {
Item item = ((IndexableItem) indexableObject).getIndexedObject();
List<Bundle> bundles = item.getBundles();
if (bundles != null) {
for (Bundle bundle : bundles) {

View File

@@ -23,6 +23,7 @@ import org.dspace.content.authority.service.ChoiceAuthorityService;
import org.dspace.content.authority.service.MetadataAuthorityService;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.discovery.indexobject.IndexableItem;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.sort.OrderFormat;
import org.dspace.sort.SortException;
@@ -56,12 +57,12 @@ public class SolrServiceMetadataBrowseIndexingPlugin implements SolrServiceIndex
protected ChoiceAuthorityService choiceAuthorityService;
@Override
public void additionalIndex(Context context, IndexableObject dso, SolrInputDocument document) {
public void additionalIndex(Context context, IndexableObject indexableObject, SolrInputDocument document) {
// Only works for Items
if (!(dso instanceof Item)) {
if (!(indexableObject instanceof IndexableItem)) {
return;
}
Item item = (Item) dso;
Item item = ((IndexableItem) indexableObject).getIndexedObject();
// Get the currently configured browse indexes
BrowseIndex[] bis;
@@ -206,9 +207,9 @@ public class SolrServiceMetadataBrowseIndexingPlugin implements SolrServiceIndex
bi.getDataType());
distFValues
.add(nLabel
+ SolrServiceImpl.FILTER_SEPARATOR
+ SearchUtils.FILTER_SEPARATOR
+ preferedLabel
+ SolrServiceImpl.AUTHORITY_SEPARATOR
+ SearchUtils.AUTHORITY_SEPARATOR
+ values.get(x).getAuthority());
distValuesForAC.add(preferedLabel);
}
@@ -222,9 +223,9 @@ public class SolrServiceMetadataBrowseIndexingPlugin implements SolrServiceIndex
bi.getDataType());
distFValues
.add(nVal
+ SolrServiceImpl.FILTER_SEPARATOR
+ SearchUtils.FILTER_SEPARATOR
+ var
+ SolrServiceImpl.AUTHORITY_SEPARATOR
+ SearchUtils.AUTHORITY_SEPARATOR
+ values.get(x).getAuthority());
distValuesForAC.add(var);
}
@@ -241,7 +242,7 @@ public class SolrServiceMetadataBrowseIndexingPlugin implements SolrServiceIndex
bi.getDataType());
distFValues
.add(nVal
+ SolrServiceImpl.FILTER_SEPARATOR
+ SearchUtils.FILTER_SEPARATOR
+ values.get(x).getValue());
distFVal.add(values.get(x).getValue());
distValuesForAC.add(values.get(x).getValue());

View File

@@ -24,6 +24,7 @@ import org.dspace.content.service.CommunityService;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.dspace.discovery.indexobject.IndexableDSpaceObject;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.eperson.service.GroupService;
@@ -56,8 +57,8 @@ public class SolrServiceResourceRestrictionPlugin implements SolrServiceIndexPlu
@Override
public void additionalIndex(Context context, IndexableObject idxObj, SolrInputDocument document) {
if (idxObj instanceof DSpaceObject) {
DSpaceObject dso = (DSpaceObject) idxObj;
if (idxObj instanceof IndexableDSpaceObject) {
DSpaceObject dso = ((IndexableDSpaceObject) idxObj).getIndexedObject();
try {
List<ResourcePolicy> policies = authorizeService.getPoliciesActionFilter(context, dso, Constants.READ);
for (ResourcePolicy resourcePolicy : policies) {

View File

@@ -14,6 +14,7 @@ import org.dspace.content.Item;
import org.dspace.content.MetadataValue;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.discovery.indexobject.IndexableItem;
import org.springframework.beans.factory.annotation.Autowired;
/**
@@ -29,9 +30,9 @@ public class SolrServiceSpellIndexingPlugin implements SolrServiceIndexPlugin {
protected ItemService itemService;
@Override
public void additionalIndex(Context context, IndexableObject dso, SolrInputDocument document) {
if (dso instanceof Item) {
Item item = (Item) dso;
public void additionalIndex(Context context, IndexableObject indexableObject, SolrInputDocument document) {
if (indexableObject instanceof IndexableItem) {
Item item = ((IndexableItem) indexableObject).getIndexedObject();
List<MetadataValue> dcValues = itemService.getMetadata(item, Item.ANY, Item.ANY, Item.ANY, Item.ANY);
List<String> toIgnoreMetadataFields = SearchUtils.getIgnoredMetadataFields(item.getType());
for (MetadataValue dcValue : dcValues) {

View File

@@ -13,8 +13,8 @@ import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.dspace.content.DSpaceObject;
import org.dspace.discovery.IndexableObject;
import org.dspace.discovery.indexobject.IndexableDSpaceObject;
import org.dspace.services.factory.DSpaceServicesFactory;
/**
@@ -45,8 +45,8 @@ public class DiscoveryConfigurationService {
String name;
if (dso == null) {
name = "site";
} else if (dso instanceof DSpaceObject) {
name = ((DSpaceObject) dso).getHandle();
} else if (dso instanceof IndexableDSpaceObject) {
name = ((IndexableDSpaceObject) dso).getIndexedObject().getHandle();
} else {
name = dso.getUniqueIndexID();
}

View File

@@ -0,0 +1,99 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.discovery.indexobject;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.common.SolrInputDocument;
import org.dspace.core.Context;
import org.dspace.discovery.indexobject.factory.ClaimedTaskIndexFactory;
import org.dspace.discovery.indexobject.factory.WorkflowItemIndexFactory;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.xmlworkflow.storedcomponents.ClaimedTask;
import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Factory implementation for indexing/retrieving claimed tasks in the search core
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class ClaimedTaskIndexFactoryImpl extends IndexFactoryImpl<IndexableClaimedTask, ClaimedTask>
implements ClaimedTaskIndexFactory {
@Autowired
protected ClaimedTaskService claimedTaskService;
@Autowired
WorkflowItemIndexFactory indexableWorkflowItemService;
@Override
public Iterator<IndexableClaimedTask> findAll(Context context) throws SQLException {
final Iterator<ClaimedTask> claimedTasks = claimedTaskService.findAll(context).iterator();
return new Iterator<IndexableClaimedTask>() {
@Override
public boolean hasNext() {
return claimedTasks.hasNext();
}
@Override
public IndexableClaimedTask next() {
return new IndexableClaimedTask(claimedTasks.next());
}
};
}
@Override
public String getType() {
return IndexableClaimedTask.TYPE;
}
@Override
public SolrInputDocument buildDocument(Context context, IndexableClaimedTask indexableObject)
throws SQLException, IOException {
// Add the ID's, types and call the SolrServiceIndexPlugins
final SolrInputDocument doc = super.buildDocument(context, indexableObject);
final ClaimedTask claimedTask = indexableObject.getIndexedObject();
// Add submitter, locations and modification time
indexableWorkflowItemService.storeInprogressItemFields(context, doc, claimedTask.getWorkflowItem());
addFacetIndex(doc, "action", claimedTask.getActionID(), claimedTask.getActionID());
addFacetIndex(doc, "step", claimedTask.getStepID(), claimedTask.getStepID());
doc.addField("taskfor", "e" + claimedTask.getOwner().getID().toString());
String acvalue = DSpaceServicesFactory.getInstance().getConfigurationService()
.getProperty("discovery.facet.namedtype.workflow.claimed");
if (StringUtils.isBlank(acvalue)) {
acvalue = indexableObject.getTypeText();
}
addNamedResourceTypeIndex(doc, acvalue);
return doc;
}
@Override
public boolean supports(Object object) {
return object instanceof ClaimedTask;
}
@Override
public List getIndexableObjects(Context context, ClaimedTask object) {
return Arrays.asList(new IndexableClaimedTask(object));
}
@Override
public Optional<IndexableClaimedTask> findIndexableObject(Context context, String id) throws SQLException {
final ClaimedTask claimedTask = claimedTaskService.find(context, Integer.parseInt(id));
return claimedTask == null ? Optional.empty() : Optional.of(new IndexableClaimedTask(claimedTask));
}
}

View File

@@ -0,0 +1,158 @@
/**
* 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.discovery.indexobject;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.apache.solr.common.SolrInputDocument;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.CollectionService;
import org.dspace.content.service.CommunityService;
import org.dspace.core.Context;
import org.dspace.discovery.SearchUtils;
import org.dspace.discovery.configuration.DiscoveryConfiguration;
import org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration;
import org.dspace.discovery.configuration.DiscoveryHitHighlightingConfiguration;
import org.dspace.discovery.indexobject.factory.CollectionIndexFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Factory implementation for indexing/retrieving collections in the search core
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class CollectionIndexFactoryImpl extends DSpaceObjectIndexFactoryImpl<IndexableCollection, Collection>
implements CollectionIndexFactory {
@Autowired
protected CollectionService collectionService;
@Autowired
protected CommunityService communityService;
@Override
public Iterator<IndexableCollection> findAll(Context context) throws SQLException {
Iterator<Collection> collections = collectionService.findAll(context).iterator();
return new Iterator<IndexableCollection>() {
@Override
public boolean hasNext() {
return collections.hasNext();
}
@Override
public IndexableCollection next() {
return new IndexableCollection(collections.next());
}
};
}
@Override
public String getType() {
return IndexableCollection.TYPE;
}
/**
* Build a solr document for a DSpace Collection.
*
* @param context The relevant DSpace Context.
* @param indexableCollection indexableCollection to be indexed
* @throws SQLException sql exception
* @throws IOException IO exception
*/
@Override
public SolrInputDocument buildDocument(Context context, IndexableCollection indexableCollection)
throws IOException, SQLException {
// Create Lucene Document and add the ID's, types and call the SolrServiceIndexPlugins
SolrInputDocument doc = super.buildDocument(context, indexableCollection);
final Collection collection = indexableCollection.getIndexedObject();
// Retrieve configuration
DiscoveryConfiguration discoveryConfiguration = SearchUtils.getDiscoveryConfiguration(collection);
DiscoveryHitHighlightingConfiguration highlightingConfiguration = discoveryConfiguration
.getHitHighlightingConfiguration();
List<String> highlightedMetadataFields = new ArrayList<>();
if (highlightingConfiguration != null) {
for (DiscoveryHitHighlightFieldConfiguration configuration : highlightingConfiguration
.getMetadataFields()) {
highlightedMetadataFields.add(configuration.getField());
}
}
// Add collection metadata
String description = collectionService.getMetadata(collection, "introductory_text");
String description_abstract = collectionService.getMetadata(collection, "short_description");
String description_table = collectionService.getMetadata(collection, "side_bar_text");
String provenance = collectionService.getMetadata(collection, "provenance_description");
String rights = collectionService.getMetadata(collection, "copyright_text");
String rights_license = collectionService.getMetadata(collection, "license");
String title = collectionService.getMetadata(collection, "name");
List<String> toIgnoreMetadataFields = SearchUtils.getIgnoredMetadataFields(collection.getType());
addContainerMetadataField(doc, highlightedMetadataFields, toIgnoreMetadataFields, "dc.description",
description);
addContainerMetadataField(doc, highlightedMetadataFields, toIgnoreMetadataFields, "dc.description.abstract",
description_abstract);
addContainerMetadataField(doc, highlightedMetadataFields, toIgnoreMetadataFields,
"dc.description.tableofcontents", description_table);
addContainerMetadataField(doc, highlightedMetadataFields, toIgnoreMetadataFields, "dc.provenance", provenance);
addContainerMetadataField(doc, highlightedMetadataFields, toIgnoreMetadataFields, "dc.rights", rights);
addContainerMetadataField(doc, highlightedMetadataFields, toIgnoreMetadataFields, "dc.rights.license",
rights_license);
addContainerMetadataField(doc, highlightedMetadataFields, toIgnoreMetadataFields, "dc.title", title);
return doc;
}
@Override
public boolean supports(Object object) {
return object instanceof Collection;
}
@Override
public List getIndexableObjects(Context context, Collection object) {
return Arrays.asList(new IndexableCollection(object));
}
@Override
public Optional<IndexableCollection> findIndexableObject(Context context, String id) throws SQLException {
final Collection collection = (collectionService.find(context, UUID.fromString(id)));
return collection == null ? Optional.empty() : Optional.of(new IndexableCollection(collection));
}
@Override
public List<String> getLocations(Context context, IndexableCollection indexableCollection) throws SQLException {
return getCollectionLocations(context, indexableCollection.getIndexedObject());
}
@Override
public List<String> getCollectionLocations(Context context, Collection collection) throws SQLException {
List<String> locations = new ArrayList<>();
// build list of community ids
List<Community> communities = ContentServiceFactory.getInstance().getCommunityService().
getAllParents(context, collection);
// now put those into strings
for (Community community : communities) {
locations.add("m" + community.getID());
}
return locations;
}
}

View File

@@ -0,0 +1,131 @@
/**
* 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.discovery.indexobject;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.apache.solr.common.SolrInputDocument;
import org.dspace.content.Community;
import org.dspace.content.service.CommunityService;
import org.dspace.core.Context;
import org.dspace.discovery.SearchUtils;
import org.dspace.discovery.configuration.DiscoveryConfiguration;
import org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration;
import org.dspace.discovery.configuration.DiscoveryHitHighlightingConfiguration;
import org.dspace.discovery.indexobject.factory.CommunityIndexFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Factory implementation for indexing/retrieving communities in the search core
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class CommunityIndexFactoryImpl extends DSpaceObjectIndexFactoryImpl<IndexableCommunity, Community>
implements CommunityIndexFactory {
@Autowired(required = true)
protected CommunityService communityService;
@Override
public Iterator<IndexableCommunity> findAll(Context context) throws SQLException {
Iterator<Community> communities = communityService.findAll(context).iterator();
return new Iterator<IndexableCommunity>() {
@Override
public boolean hasNext() {
return communities.hasNext();
}
@Override
public IndexableCommunity next() {
return new IndexableCommunity(communities.next());
}
};
}
@Override
public String getType() {
return IndexableCommunity.TYPE;
}
@Override
public SolrInputDocument buildDocument(Context context, IndexableCommunity indexableObject)
throws SQLException, IOException {
// Add the ID's, types and call the SolrServiceIndexPlugins
SolrInputDocument doc = super.buildDocument(context, indexableObject);
final Community community = indexableObject.getIndexedObject();
// Retrieve configuration
DiscoveryConfiguration discoveryConfiguration = SearchUtils.getDiscoveryConfiguration(community);
DiscoveryHitHighlightingConfiguration highlightingConfiguration = discoveryConfiguration
.getHitHighlightingConfiguration();
List<String> highlightedMetadataFields = new ArrayList<String>();
if (highlightingConfiguration != null) {
for (DiscoveryHitHighlightFieldConfiguration configuration : highlightingConfiguration
.getMetadataFields()) {
highlightedMetadataFields.add(configuration.getField());
}
}
// Add community metadata
String description = communityService.getMetadata(community, "introductory_text");
String description_abstract = communityService.getMetadata(community, "short_description");
String description_table = communityService.getMetadata(community, "side_bar_text");
String rights = communityService.getMetadata(community, "copyright_text");
String title = communityService.getMetadata(community, "name");
List<String> toIgnoreMetadataFields = SearchUtils.getIgnoredMetadataFields(community.getType());
addContainerMetadataField(doc, highlightedMetadataFields, toIgnoreMetadataFields, "dc.description",
description);
addContainerMetadataField(doc, highlightedMetadataFields, toIgnoreMetadataFields, "dc.description.abstract",
description_abstract);
addContainerMetadataField(doc, highlightedMetadataFields, toIgnoreMetadataFields,
"dc.description.tableofcontents", description_table);
addContainerMetadataField(doc, highlightedMetadataFields, toIgnoreMetadataFields, "dc.rights", rights);
addContainerMetadataField(doc, highlightedMetadataFields, toIgnoreMetadataFields, "dc.title", title);
return doc;
}
@Override
public boolean supports(Object object) {
return object instanceof Community;
}
@Override
public List getIndexableObjects(Context context, Community object) {
return Arrays.asList(new IndexableCommunity(object));
}
@Override
public Optional<IndexableCommunity> findIndexableObject(Context context, String id) throws SQLException {
final Community community = communityService.find(context, UUID.fromString(id));
return community == null ? Optional.empty() : Optional.of(new IndexableCommunity(community));
}
@Override
public List<String> getLocations(Context context, IndexableCommunity indexableDSpaceObject) throws SQLException {
final Community target = indexableDSpaceObject.getIndexedObject();
List<String> locations = new ArrayList<>();
// build list of community ids
List<Community> communities = target.getParentCommunities();
// now put those into strings
for (Community community : communities) {
locations.add("m" + community.getID());
}
return locations;
}
}

View File

@@ -0,0 +1,80 @@
/**
* 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.discovery.indexobject;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.common.SolrInputDocument;
import org.dspace.content.DSpaceObject;
import org.dspace.core.Context;
import org.dspace.discovery.indexobject.factory.DSpaceObjectIndexFactory;
/**
* Factory implementation for indexing/retrieving DSpaceObjects in the search core
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public abstract class DSpaceObjectIndexFactoryImpl<T extends IndexableDSpaceObject, S extends DSpaceObject>
extends IndexFactoryImpl<T, S> implements DSpaceObjectIndexFactory<T, S> {
@Override
public SolrInputDocument buildDocument(Context context, T indexableObject) throws SQLException, IOException {
// Add the ID's, types and call the SolrServiceIndexPlugins
SolrInputDocument doc = super.buildDocument(context, indexableObject);
final DSpaceObject dso = indexableObject.getIndexedObject();
// want to be able to search for handle, so use keyword
// (not tokenized, but it is indexed)
if (dso.getHandle() != null) {
// want to be able to search for handle, so use keyword
// (not tokenized, but it is indexed)
doc.addField("handle", dso.getHandle());
}
final List<String> locations = getLocations(context, indexableObject);
storeCommunityCollectionLocations(doc, locations);
return doc;
}
/**
* Add the metadata value of the community/collection to the solr document
* IF needed highlighting is added !
*
* @param doc the solr document
* @param highlightedMetadataFields the list of metadata fields that CAN be highlighted
* @param toIgnoreMetadataFields the list of metadata fields to skip adding to Solr
* @param metadataField the metadata field added
* @param value the value (can be NULL !)
*/
protected void addContainerMetadataField(SolrInputDocument doc, List<String> highlightedMetadataFields,
List<String> toIgnoreMetadataFields, String metadataField, String value) {
if ((toIgnoreMetadataFields == null || !toIgnoreMetadataFields.contains(metadataField))
&& StringUtils.isNotBlank(value)) {
doc.addField(metadataField, value);
if (highlightedMetadataFields.contains(metadataField)) {
doc.addField(metadataField + "_hl", value);
}
}
}
@Override
public void storeCommunityCollectionLocations(SolrInputDocument doc, List<String> locations) {
if (locations != null) {
for (String location : locations) {
doc.addField("location", location);
if (location.startsWith("m")) {
doc.addField("location.comm", location.substring(1));
} else {
doc.addField("location.coll", location.substring(1));
}
}
}
}
}

View File

@@ -0,0 +1,193 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.discovery.indexobject;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.request.AbstractUpdateRequest;
import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.handler.extraction.ExtractingParams;
import org.dspace.core.Context;
import org.dspace.discovery.FullTextContentStreams;
import org.dspace.discovery.IndexableObject;
import org.dspace.discovery.SearchUtils;
import org.dspace.discovery.SolrSearchCore;
import org.dspace.discovery.SolrServiceIndexPlugin;
import org.dspace.discovery.indexobject.factory.IndexFactory;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.util.SolrUtils;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Basis factory interface implementation for indexing/retrieving any IndexableObject in the search core
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public abstract class IndexFactoryImpl<T extends IndexableObject, S> implements IndexFactory<T, S> {
@Autowired
protected List<SolrServiceIndexPlugin> solrServiceIndexPlugins;
@Autowired
protected SolrSearchCore solrSearchCore;
@Override
public SolrInputDocument buildDocument(Context context, T indexableObject) throws SQLException, IOException {
SolrInputDocument doc = new SolrInputDocument();
// want to be able to check when last updated
// (not tokenized, but it is indexed)
doc.addField(SearchUtils.LAST_INDEXED_FIELD, SolrUtils.getDateFormatter().format(new Date()));
// New fields to weaken the dependence on handles, and allow for faster
// list display
doc.addField(SearchUtils.RESOURCE_UNIQUE_ID, indexableObject.getType() + "-" + indexableObject.getID());
doc.addField(SearchUtils.RESOURCE_TYPE_FIELD, indexableObject.getType());
doc.addField(SearchUtils.RESOURCE_ID_FIELD, indexableObject.getID().toString());
//Do any additional indexing, depends on the plugins
for (SolrServiceIndexPlugin solrServiceIndexPlugin : solrServiceIndexPlugins) {
solrServiceIndexPlugin.additionalIndex(context, indexableObject, doc);
}
return doc;
}
@Override
public void writeDocument(Context context, T indexableObject, SolrInputDocument solrInputDocument)
throws SQLException, IOException, SolrServerException {
writeDocument(solrInputDocument, null);
}
/**
* Write the document to the index under the appropriate unique identifier.
*
* @param doc the solr document to be written to the server
* @param streams list of bitstream content streams DiscoverQueryBuilderTest.java:285
* @throws IOException A general class of exceptions produced by failed or interrupted I/O operations.
*/
protected void writeDocument(SolrInputDocument doc, FullTextContentStreams streams)
throws IOException, SolrServerException {
final SolrClient solr = solrSearchCore.getSolr();
if (solr != null) {
if (streams != null && !streams.isEmpty()) {
ContentStreamUpdateRequest req = new ContentStreamUpdateRequest("/update/extract");
req.addContentStream(streams);
ModifiableSolrParams params = new ModifiableSolrParams();
//req.setParam(ExtractingParams.EXTRACT_ONLY, "true");
for (String name : doc.getFieldNames()) {
for (Object val : doc.getFieldValues(name)) {
params.add(ExtractingParams.LITERALS_PREFIX + name, val.toString());
}
}
req.setParams(params);
req.setParam(ExtractingParams.UNKNOWN_FIELD_PREFIX, "attr_");
req.setParam(ExtractingParams.MAP_PREFIX + "content", "fulltext");
req.setParam(ExtractingParams.EXTRACT_FORMAT, "text");
req.setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true);
req.process(solr);
} else {
solr.add(doc);
}
}
}
/**
* Index the provided value as use for a sidebar facet
* @param document The solr document
* @param field The facet field name
* @param authority The authority linked to the field
* @param fvalue The display value for the facet
*/
protected void addFacetIndex(SolrInputDocument document, String field, String authority, String fvalue) {
addFacetIndex(document, field, fvalue, authority, fvalue);
}
/**
* Index the provided value as use for a sidebar facet
* @param document The solr document
* @param field The facet field name
* @param sortValue The value on which we should sort our facet fields when retrieving
* @param authority The authority linked to the field
* @param fvalue The display value for the facet
*/
protected void addFacetIndex(SolrInputDocument document, String field, String sortValue, String authority,
String fvalue) {
// the separator for the filter can be eventually configured
String separator = DSpaceServicesFactory.getInstance().getConfigurationService()
.getProperty("discovery.solr.facets.split.char");
if (separator == null) {
separator = SearchUtils.FILTER_SEPARATOR;
}
String acvalue = sortValue + separator + fvalue + SearchUtils.AUTHORITY_SEPARATOR + authority;
document.addField(field + "_filter", acvalue);
// build the solr field used for the keyword search
document.addField(field + "_keyword", fvalue);
// build the solr fields used for the autocomplete
document.addField(field + "_ac", fvalue.toLowerCase() + separator + fvalue);
if (StringUtils.isNotBlank(authority)) {
document.addField(field + "_acid", fvalue.toLowerCase() + separator + fvalue
+ SearchUtils.AUTHORITY_SEPARATOR + authority);
document.addField(field + "_authority", authority);
}
}
/**
* Add the necessary fields to the SOLR document to support a Discover Facet on resourcetypename (archived item,
* workspace item, workflow item, etc)
*
* @param document the solr document
* @param filterValue the filter value (i.e. <sort_value>\n|||\n<display_value>###<authority_value>
*/
protected void addNamedResourceTypeIndex(SolrInputDocument document, String filterValue) {
// the separator for the filter can be eventually configured
String separator = DSpaceServicesFactory.getInstance().getConfigurationService()
.getProperty("discovery.solr.facets.split.char");
if (separator == null) {
separator = SearchUtils.FILTER_SEPARATOR;
}
// split the authority part from the sort/display
String[] avalues = filterValue.split(SearchUtils.AUTHORITY_SEPARATOR);
String sortValue = avalues[0];
String authorityValue = avalues.length == 2 ? avalues[1] : filterValue;
// get the display value
int idxSeparator = sortValue.indexOf(separator);
String displayValue = idxSeparator != -1 ? sortValue.substring(idxSeparator + separator.length())
: sortValue;
addFacetIndex(document, SearchUtils.NAMED_RESOURCE_TYPE, sortValue, authorityValue, displayValue);
}
@Override
public void delete(T indexableObject) throws IOException, SolrServerException {
solrSearchCore.getSolr().deleteById(indexableObject.getUniqueIndexID());
}
@Override
public void delete(String indexableObjectIdentifier) throws IOException, SolrServerException {
solrSearchCore.getSolr().deleteById(indexableObjectIdentifier);
}
@Override
public void deleteAll() throws IOException, SolrServerException {
solrSearchCore.getSolr().deleteByQuery(SearchUtils.RESOURCE_TYPE_FIELD + ":" + getType());
}
}

View File

@@ -0,0 +1,51 @@
/**
* 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.discovery.indexobject;
import org.dspace.discovery.IndexableObject;
import org.dspace.xmlworkflow.storedcomponents.ClaimedTask;
/**
* ClaimedTask implementation for the IndexableObject
*
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class IndexableClaimedTask implements IndexableObject<ClaimedTask, Integer> {
private ClaimedTask claimedTask;
public static final String TYPE = ClaimedTask.class.getSimpleName();
public IndexableClaimedTask(ClaimedTask claimedTask) {
this.claimedTask = claimedTask;
}
@Override
public ClaimedTask getIndexedObject() {
return claimedTask;
}
@Override
public void setIndexedObject(ClaimedTask claimedTask) {
this.claimedTask = claimedTask;
}
@Override
public String getType() {
return TYPE;
}
@Override
public Integer getID() {
return claimedTask.getID();
}
@Override
public String getTypeText() {
return "CLAIMEDTASK";
}
}

View File

@@ -0,0 +1,35 @@
/**
* 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.discovery.indexobject;
import org.dspace.content.Collection;
import org.dspace.core.Constants;
/**
* Collection implementation for the IndexableObject
*
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class IndexableCollection extends IndexableDSpaceObject<Collection> {
public static final String TYPE = Collection.class.getSimpleName();
public IndexableCollection(Collection dso) {
super(dso);
}
@Override
public String getType() {
return TYPE;
}
@Override
public String getTypeText() {
return Constants.typeText[Constants.COLLECTION];
}
}

View File

@@ -0,0 +1,34 @@
/**
* 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.discovery.indexobject;
import org.dspace.content.Community;
import org.dspace.core.Constants;
/**
* Community implementation for the IndexableObject
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class IndexableCommunity extends IndexableDSpaceObject<Community> {
public static final String TYPE = Community.class.getSimpleName();
public IndexableCommunity(Community dso) {
super(dso);
}
@Override
public String getType() {
return TYPE;
}
@Override
public String getTypeText() {
return Constants.typeText[Constants.COMMUNITY];
}
}

View File

@@ -0,0 +1,43 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.discovery.indexobject;
import java.util.UUID;
import org.dspace.content.DSpaceObject;
import org.dspace.discovery.IndexableObject;
/**
* DSpaceObject implementation for the IndexableObject, contains methods used by all DSpaceObject methods
* All DSpaceObjects that will be indexed in discovery should inherit from this class & have their own implementation
*
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public abstract class IndexableDSpaceObject<T extends DSpaceObject> implements IndexableObject<T, UUID> {
private T dso;
public IndexableDSpaceObject(T dso) {
this.dso = dso;
}
@Override
public T getIndexedObject() {
return dso;
}
@Override
public void setIndexedObject(T dso) {
this.dso = dso;
}
@Override
public UUID getID() {
return dso.getID();
}
}

View File

@@ -0,0 +1,35 @@
/**
* 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.discovery.indexobject;
import org.dspace.content.InProgressSubmission;
import org.dspace.discovery.IndexableObject;
/**
* InProgressSubmission implementation for the IndexableObject
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public abstract class IndexableInProgressSubmission<T extends InProgressSubmission>
implements IndexableObject<T, Integer> {
protected T inProgressSubmission;
public IndexableInProgressSubmission(T inProgressSubmission) {
this.inProgressSubmission = inProgressSubmission;
}
@Override
public T getIndexedObject() {
return inProgressSubmission;
}
@Override
public void setIndexedObject(T inProgressSubmission) {
this.inProgressSubmission = inProgressSubmission;
}
}

View File

@@ -0,0 +1,41 @@
/**
* 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.discovery.indexobject;
import java.util.Date;
import org.dspace.content.Item;
import org.dspace.core.Constants;
/**
* Item implementation for the IndexableObject
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class IndexableItem extends IndexableDSpaceObject<Item> {
public static final String TYPE = Item.class.getSimpleName();
public IndexableItem(Item dso) {
super(dso);
}
@Override
public Date getLastModified() {
return getIndexedObject().getLastModified();
}
@Override
public String getType() {
return TYPE;
}
@Override
public String getTypeText() {
return Constants.typeText[Constants.ITEM];
}
}

View File

@@ -0,0 +1,51 @@
/**
* 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.discovery.indexobject;
import org.dspace.discovery.IndexableObject;
import org.dspace.xmlworkflow.storedcomponents.PoolTask;
/**
* PoolTask implementation for the IndexableObject
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class IndexablePoolTask implements IndexableObject<PoolTask, Integer> {
public static final String TYPE = PoolTask.class.getSimpleName();
private PoolTask poolTask;
public IndexablePoolTask(PoolTask poolTask) {
this.poolTask = poolTask;
}
@Override
public PoolTask getIndexedObject() {
return poolTask;
}
@Override
public void setIndexedObject(PoolTask poolTask) {
this.poolTask = poolTask;
}
@Override
public String getType() {
return TYPE;
}
@Override
public String getTypeText() {
return "POOLTASK";
}
@Override
public Integer getID() {
return poolTask.getID();
}
}

View File

@@ -0,0 +1,38 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.discovery.indexobject;
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
/**
* Workflow item implementation for the IndexableObject
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class IndexableWorkflowItem extends IndexableInProgressSubmission<XmlWorkflowItem> {
public static final String TYPE = XmlWorkflowItem.class.getSimpleName();
public IndexableWorkflowItem(XmlWorkflowItem inProgressSubmission) {
super(inProgressSubmission);
}
@Override
public String getType() {
return TYPE;
}
@Override
public String getTypeText() {
return "WORKFLOWITEM";
}
@Override
public Integer getID() {
return getIndexedObject().getID();
}
}

View File

@@ -0,0 +1,38 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.discovery.indexobject;
import org.dspace.content.WorkspaceItem;
/**
* Workspace item implementation for the IndexableObject
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class IndexableWorkspaceItem extends IndexableInProgressSubmission<WorkspaceItem> {
public static final String TYPE = WorkspaceItem.class.getSimpleName();
public IndexableWorkspaceItem(WorkspaceItem inProgressSubmission) {
super(inProgressSubmission);
}
@Override
public String getType() {
return TYPE;
}
@Override
public Integer getID() {
return getIndexedObject().getID();
}
@Override
public String getTypeText() {
return "WORKSPACEITEM";
}
}

View File

@@ -0,0 +1,66 @@
/**
* 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.discovery.indexobject;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import org.apache.solr.common.SolrInputDocument;
import org.dspace.content.InProgressSubmission;
import org.dspace.content.Item;
import org.dspace.core.Context;
import org.dspace.discovery.indexobject.factory.CollectionIndexFactory;
import org.dspace.discovery.indexobject.factory.InprogressSubmissionIndexFactory;
import org.dspace.discovery.indexobject.factory.ItemIndexFactory;
import org.dspace.eperson.EPerson;
import org.dspace.util.SolrUtils;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Factory implementation for indexing/retrieving InProgressSubmissions in the search core
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public abstract class InprogressSubmissionIndexFactoryImpl
<T extends IndexableInProgressSubmission, S extends InProgressSubmission> extends IndexFactoryImpl<T, S>
implements InprogressSubmissionIndexFactory<T, S> {
@Autowired
protected CollectionIndexFactory indexableCollectionService;
@Autowired
protected ItemIndexFactory indexableItemService;
@Override
public SolrInputDocument buildDocument(Context context, T indexableObject) throws SQLException, IOException {
// Add the ID's, types and call the SolrServiceIndexPlugins
SolrInputDocument doc = super.buildDocument(context, indexableObject);
// Add submitter, locations and modification time
storeInprogressItemFields(context, doc, indexableObject.getIndexedObject());
return doc;
}
@Override
public void storeInprogressItemFields(Context context, SolrInputDocument doc,
InProgressSubmission inProgressSubmission) throws SQLException {
final Item item = inProgressSubmission.getItem();
doc.addField("lastModified", SolrUtils.getDateFormatter().format(item.getLastModified()));
EPerson submitter = inProgressSubmission.getSubmitter();
if (submitter != null) {
addFacetIndex(doc, "submitter", submitter.getID().toString(),
submitter.getFullName());
}
doc.addField("inprogress.item", new IndexableItem(inProgressSubmission.getItem()).getUniqueIndexID());
// get the location string (for searching by collection & community)
List<String> locations = indexableCollectionService.
getCollectionLocations(context, inProgressSubmission.getCollection());
indexableCollectionService.storeCommunityCollectionLocations(doc, locations);
}
}

View File

@@ -0,0 +1,733 @@
/**
* 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.discovery.indexobject;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.logging.log4j.Logger;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.common.SolrInputDocument;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.Item;
import org.dspace.content.MetadataField;
import org.dspace.content.MetadataSchema;
import org.dspace.content.MetadataValue;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.authority.Choices;
import org.dspace.content.authority.service.ChoiceAuthorityService;
import org.dspace.content.authority.service.MetadataAuthorityService;
import org.dspace.content.service.ItemService;
import org.dspace.content.service.WorkspaceItemService;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.dspace.discovery.FullTextContentStreams;
import org.dspace.discovery.IndexableObject;
import org.dspace.discovery.SearchUtils;
import org.dspace.discovery.configuration.DiscoveryConfiguration;
import org.dspace.discovery.configuration.DiscoveryConfigurationParameters;
import org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration;
import org.dspace.discovery.configuration.DiscoveryHitHighlightingConfiguration;
import org.dspace.discovery.configuration.DiscoveryMoreLikeThisConfiguration;
import org.dspace.discovery.configuration.DiscoveryRecentSubmissionsConfiguration;
import org.dspace.discovery.configuration.DiscoverySearchFilter;
import org.dspace.discovery.configuration.DiscoverySearchFilterFacet;
import org.dspace.discovery.configuration.DiscoverySortConfiguration;
import org.dspace.discovery.configuration.DiscoverySortFieldConfiguration;
import org.dspace.discovery.configuration.HierarchicalSidebarFacetConfiguration;
import org.dspace.discovery.indexobject.factory.ItemIndexFactory;
import org.dspace.discovery.indexobject.factory.WorkflowItemIndexFactory;
import org.dspace.discovery.indexobject.factory.WorkspaceItemIndexFactory;
import org.dspace.eperson.EPerson;
import org.dspace.handle.service.HandleService;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.util.MultiFormatDateParser;
import org.dspace.util.SolrUtils;
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Factory implementation for indexing/retrieving items in the search core
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class ItemIndexFactoryImpl extends DSpaceObjectIndexFactoryImpl<IndexableItem, Item>
implements ItemIndexFactory {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(ItemIndexFactoryImpl.class);
public static final String VARIANTS_STORE_SEPARATOR = "###";
public static final String STORE_SEPARATOR = "\n|||\n";
@Autowired
protected HandleService handleService;
@Autowired
protected ItemService itemService;
@Autowired(required = true)
protected ChoiceAuthorityService choiceAuthorityService;
@Autowired
protected MetadataAuthorityService metadataAuthorityService;
@Autowired
protected WorkspaceItemService workspaceItemService;
@Autowired
protected XmlWorkflowItemService xmlWorkflowItemService;
@Autowired
protected WorkflowItemIndexFactory workflowItemIndexFactory;
@Autowired
protected WorkspaceItemIndexFactory workspaceItemIndexFactory;
@Override
public Iterator<IndexableItem> findAll(Context context) throws SQLException {
Iterator<Item> items = itemService.findAllUnfiltered(context);
return new Iterator<IndexableItem>() {
@Override
public boolean hasNext() {
return items.hasNext();
}
@Override
public IndexableItem next() {
return new IndexableItem(items.next());
}
};
}
@Override
public String getType() {
return IndexableItem.TYPE;
}
/**
* Build a Solr document for a DSpace Item and write the index
*
* @param context Users Context
* @param indexableItem The IndexableItem Item to be indexed
* @throws SQLException if database error
* @throws IOException if IO error
*/
@Override
public SolrInputDocument buildDocument(Context context, IndexableItem indexableItem)
throws SQLException, IOException {
// Add the ID's, types and call the SolrServiceIndexPlugins
SolrInputDocument doc = super.buildDocument(context, indexableItem);
final Item item = indexableItem.getIndexedObject();
doc.addField("archived", item.isArchived());
doc.addField("withdrawn", item.isWithdrawn());
doc.addField("discoverable", item.isDiscoverable());
doc.addField("lastModified", SolrUtils.getDateFormatter().format(item.getLastModified()));
EPerson submitter = item.getSubmitter();
if (submitter != null) {
addFacetIndex(doc, "submitter", submitter.getID().toString(),
submitter.getFullName());
}
// Add the item metadata
List<DiscoveryConfiguration> discoveryConfigurations = SearchUtils.getAllDiscoveryConfigurations(item);
addDiscoveryFields(doc, context, indexableItem.getIndexedObject(), discoveryConfigurations);
//mandatory facet to show status on mydspace
final String typeText = StringUtils.deleteWhitespace(indexableItem.getTypeText().toLowerCase());
String acvalue = DSpaceServicesFactory.getInstance().getConfigurationService().getProperty(
"discovery.facet.namedtype." + typeText,
typeText + SearchUtils.AUTHORITY_SEPARATOR + typeText);
if (StringUtils.isNotBlank(acvalue)) {
addNamedResourceTypeIndex(doc, acvalue);
}
// write the index and close the inputstreamreaders
try {
log.info("Wrote Item: " + item.getID() + " to Index");
} catch (RuntimeException e) {
log.error("Error while writing item to discovery index: " + item.getID() + " message:"
+ e.getMessage(), e);
}
return doc;
}
@Override
public void addDiscoveryFields(SolrInputDocument doc, Context context, Item item,
List<DiscoveryConfiguration> discoveryConfigurations)
throws SQLException, IOException {
//Keep a list of our sort values which we added, sort values can only be added once
List<String> sortFieldsAdded = new ArrayList<>();
Map<String, List<DiscoverySearchFilter>> searchFilters = null;
Set<String> hitHighlightingFields = new HashSet<>();
try {
//A map used to save each sidebarFacet config by the metadata fields
searchFilters = new HashMap<>();
Map<String, DiscoverySortFieldConfiguration> sortFields = new HashMap<>();
Map<String, DiscoveryRecentSubmissionsConfiguration> recentSubmissionsConfigurationMap = new
HashMap<>();
Set<String> moreLikeThisFields = new HashSet<>();
// some configuration are returned multiple times, skip them to save CPU cycles
Set<String> appliedConf = new HashSet<>();
// it is common to have search filter shared between multiple configurations
Set<String> appliedDiscoverySearchFilter = new HashSet<>();
for (DiscoveryConfiguration discoveryConfiguration : discoveryConfigurations) {
if (appliedConf.contains(discoveryConfiguration.getId())) {
continue;
} else {
appliedConf.add(discoveryConfiguration.getId());
}
for (int i = 0; i < discoveryConfiguration.getSearchFilters().size(); i++) {
if (appliedDiscoverySearchFilter
.contains(discoveryConfiguration.getSearchFilters().get(i).getIndexFieldName())) {
continue;
} else {
appliedDiscoverySearchFilter
.add(discoveryConfiguration.getSearchFilters().get(i).getIndexFieldName());
}
List<MetadataValue> metadataValueList = new LinkedList<>();
boolean shouldExposeMinMax = false;
DiscoverySearchFilter discoverySearchFilter = discoveryConfiguration.getSearchFilters().get(i);
if (StringUtils.equalsIgnoreCase(discoverySearchFilter.getFilterType(), "facet")) {
if (((DiscoverySearchFilterFacet) discoverySearchFilter).exposeMinAndMaxValue()) {
shouldExposeMinMax = true;
}
}
for (int j = 0; j < discoverySearchFilter.getMetadataFields().size(); j++) {
String metadataField = discoverySearchFilter.getMetadataFields().get(j);
List<DiscoverySearchFilter> resultingList;
if (searchFilters.get(metadataField) != null) {
resultingList = searchFilters.get(metadataField);
} else {
//New metadata field, create a new list for it
resultingList = new ArrayList<>();
}
if (shouldExposeMinMax) {
String[] splittedMetadataField = metadataField.split("\\.");
String schema = splittedMetadataField[0];
String element = splittedMetadataField.length > 1 ? splittedMetadataField[1] : null;
String qualifier = splittedMetadataField.length > 2 ? splittedMetadataField[2] : null;
metadataValueList.addAll(itemService.getMetadata(item, schema,
element, qualifier, Item.ANY));
}
resultingList.add(discoverySearchFilter);
searchFilters.put(metadataField, resultingList);
}
if (!metadataValueList.isEmpty() && shouldExposeMinMax) {
metadataValueList.sort((mdv1, mdv2) -> mdv1.getValue().compareTo(mdv2.getValue()));
MetadataValue firstMetadataValue = metadataValueList.get(0);
MetadataValue lastMetadataValue = metadataValueList.get(metadataValueList.size() - 1);
doc.addField(discoverySearchFilter.getIndexFieldName() + "_min", firstMetadataValue.getValue());
doc.addField(discoverySearchFilter.getIndexFieldName()
+ "_min_sort", firstMetadataValue.getValue());
doc.addField(discoverySearchFilter.getIndexFieldName() + "_max", lastMetadataValue.getValue());
doc.addField(discoverySearchFilter.getIndexFieldName()
+ "_max_sort", lastMetadataValue.getValue());
}
}
DiscoverySortConfiguration sortConfiguration = discoveryConfiguration.getSearchSortConfiguration();
if (sortConfiguration != null) {
for (DiscoverySortFieldConfiguration discoverySortConfiguration : sortConfiguration
.getSortFields()) {
sortFields.put(discoverySortConfiguration.getMetadataField(), discoverySortConfiguration);
}
}
DiscoveryRecentSubmissionsConfiguration recentSubmissionConfiguration = discoveryConfiguration
.getRecentSubmissionConfiguration();
if (recentSubmissionConfiguration != null) {
recentSubmissionsConfigurationMap
.put(recentSubmissionConfiguration.getMetadataSortField(), recentSubmissionConfiguration);
}
DiscoveryHitHighlightingConfiguration hitHighlightingConfiguration = discoveryConfiguration
.getHitHighlightingConfiguration();
if (hitHighlightingConfiguration != null) {
List<DiscoveryHitHighlightFieldConfiguration> fieldConfigurations = hitHighlightingConfiguration
.getMetadataFields();
for (DiscoveryHitHighlightFieldConfiguration fieldConfiguration : fieldConfigurations) {
hitHighlightingFields.add(fieldConfiguration.getField());
}
}
DiscoveryMoreLikeThisConfiguration moreLikeThisConfiguration = discoveryConfiguration
.getMoreLikeThisConfiguration();
if (moreLikeThisConfiguration != null) {
for (String metadataField : moreLikeThisConfiguration.getSimilarityMetadataFields()) {
moreLikeThisFields.add(metadataField);
}
}
}
List<String> toProjectionFields = new ArrayList<>();
String[] projectionFields = DSpaceServicesFactory.getInstance().getConfigurationService()
.getArrayProperty("discovery.index.projection");
if (projectionFields != null) {
for (String field : projectionFields) {
toProjectionFields.add(field.trim());
}
}
List<String> toIgnoreMetadataFields = SearchUtils.getIgnoredMetadataFields(item.getType());
List<MetadataValue> mydc = itemService.getMetadata(item, Item.ANY, Item.ANY, Item.ANY, Item.ANY);
for (MetadataValue meta : mydc) {
MetadataField metadataField = meta.getMetadataField();
MetadataSchema metadataSchema = metadataField.getMetadataSchema();
String field = metadataSchema.getName() + "." + metadataField.getElement();
String unqualifiedField = field;
String value = meta.getValue();
if (value == null) {
continue;
}
if (metadataField.getQualifier() != null && !metadataField.getQualifier().trim().equals("")) {
field += "." + metadataField.getQualifier();
}
//We are not indexing provenance, this is useless
if (toIgnoreMetadataFields != null && (toIgnoreMetadataFields.contains(field) || toIgnoreMetadataFields
.contains(unqualifiedField + "." + Item.ANY))) {
continue;
}
String authority = null;
String preferedLabel = null;
List<String> variants = null;
boolean isAuthorityControlled = metadataAuthorityService
.isAuthorityControlled(metadataField);
int minConfidence = isAuthorityControlled ? metadataAuthorityService
.getMinConfidence(metadataField) : Choices.CF_ACCEPTED;
if (isAuthorityControlled && meta.getAuthority() != null
&& meta.getConfidence() >= minConfidence) {
boolean ignoreAuthority =
DSpaceServicesFactory
.getInstance()
.getConfigurationService()
.getPropertyAsType("discovery.index.authority.ignore." + field,
DSpaceServicesFactory
.getInstance()
.getConfigurationService()
.getPropertyAsType("discovery.index.authority.ignore",
new Boolean(false)),
true);
if (!ignoreAuthority) {
authority = meta.getAuthority();
boolean ignorePrefered =
DSpaceServicesFactory
.getInstance()
.getConfigurationService()
.getPropertyAsType("discovery.index.authority.ignore-prefered." + field,
DSpaceServicesFactory
.getInstance()
.getConfigurationService()
.getPropertyAsType("discovery.index.authority.ignore-prefered",
new Boolean(false)),
true);
if (!ignorePrefered) {
preferedLabel = choiceAuthorityService
.getLabel(meta, meta.getLanguage());
}
boolean ignoreVariants =
DSpaceServicesFactory
.getInstance()
.getConfigurationService()
.getPropertyAsType("discovery.index.authority.ignore-variants." + field,
DSpaceServicesFactory
.getInstance()
.getConfigurationService()
.getPropertyAsType("discovery.index.authority.ignore-variants",
new Boolean(false)),
true);
if (!ignoreVariants) {
variants = choiceAuthorityService
.getVariants(meta);
}
}
}
if ((searchFilters.get(field) != null || searchFilters
.get(unqualifiedField + "." + Item.ANY) != null)) {
List<DiscoverySearchFilter> searchFilterConfigs = searchFilters.get(field);
if (searchFilterConfigs == null) {
searchFilterConfigs = searchFilters.get(unqualifiedField + "." + Item.ANY);
}
for (DiscoverySearchFilter searchFilter : searchFilterConfigs) {
Date date = null;
String separator = DSpaceServicesFactory.getInstance().getConfigurationService()
.getProperty("discovery.solr.facets.split.char");
if (separator == null) {
separator = SearchUtils.FILTER_SEPARATOR;
}
if (searchFilter.getType().equals(DiscoveryConfigurationParameters.TYPE_DATE)) {
//For our search filters that are dates we format them properly
date = MultiFormatDateParser.parse(value);
if (date != null) {
//TODO: make this date format configurable !
value = DateFormatUtils.formatUTC(date, "yyyy-MM-dd");
}
}
doc.addField(searchFilter.getIndexFieldName(), value);
doc.addField(searchFilter.getIndexFieldName() + "_keyword", value);
if (authority != null && preferedLabel == null) {
doc.addField(searchFilter.getIndexFieldName()
+ "_keyword", value + SearchUtils.AUTHORITY_SEPARATOR
+ authority);
doc.addField(searchFilter.getIndexFieldName()
+ "_authority", authority);
doc.addField(searchFilter.getIndexFieldName()
+ "_acid", value.toLowerCase()
+ separator + value
+ SearchUtils.AUTHORITY_SEPARATOR + authority);
}
if (preferedLabel != null) {
doc.addField(searchFilter.getIndexFieldName(),
preferedLabel);
doc.addField(searchFilter.getIndexFieldName()
+ "_keyword", preferedLabel);
doc.addField(searchFilter.getIndexFieldName()
+ "_keyword", preferedLabel
+ SearchUtils.AUTHORITY_SEPARATOR + authority);
doc.addField(searchFilter.getIndexFieldName()
+ "_authority", authority);
doc.addField(searchFilter.getIndexFieldName()
+ "_acid", preferedLabel.toLowerCase()
+ separator + preferedLabel
+ SearchUtils.AUTHORITY_SEPARATOR + authority);
}
if (variants != null) {
for (String var : variants) {
doc.addField(searchFilter.getIndexFieldName() + "_keyword", var);
doc.addField(searchFilter.getIndexFieldName()
+ "_acid", var.toLowerCase()
+ separator + var
+ SearchUtils.AUTHORITY_SEPARATOR + authority);
}
}
//Add a dynamic fields for auto complete in search
doc.addField(searchFilter.getIndexFieldName() + "_ac",
value.toLowerCase() + separator + value);
if (preferedLabel != null) {
doc.addField(searchFilter.getIndexFieldName()
+ "_ac", preferedLabel.toLowerCase()
+ separator + preferedLabel);
}
if (variants != null) {
for (String var : variants) {
doc.addField(searchFilter.getIndexFieldName()
+ "_ac", var.toLowerCase() + separator
+ var);
}
}
if (searchFilter.getFilterType().equals(DiscoverySearchFilterFacet.FILTER_TYPE_FACET)) {
if (searchFilter.getType().equals(DiscoveryConfigurationParameters.TYPE_TEXT)) {
//Add a special filter
//We use a separator to split up the lowercase and regular case, this is needed to
// get our filters in regular case
//Solr has issues with facet prefix and cases
if (authority != null) {
String facetValue = preferedLabel != null ? preferedLabel : value;
doc.addField(searchFilter.getIndexFieldName() + "_filter", facetValue
.toLowerCase() + separator + facetValue + SearchUtils.AUTHORITY_SEPARATOR
+ authority);
} else {
doc.addField(searchFilter.getIndexFieldName() + "_filter",
value.toLowerCase() + separator + value);
}
} else if (searchFilter.getType().equals(DiscoveryConfigurationParameters.TYPE_DATE)) {
if (date != null) {
String indexField = searchFilter.getIndexFieldName() + ".year";
String yearUTC = DateFormatUtils.formatUTC(date, "yyyy");
doc.addField(searchFilter.getIndexFieldName() + "_keyword", yearUTC);
// add the year to the autocomplete index
doc.addField(searchFilter.getIndexFieldName() + "_ac", yearUTC);
doc.addField(indexField, yearUTC);
if (yearUTC.startsWith("0")) {
doc.addField(
searchFilter.getIndexFieldName()
+ "_keyword",
yearUTC.replaceFirst("0*", ""));
// add date without starting zeros for autocomplete e filtering
doc.addField(
searchFilter.getIndexFieldName()
+ "_ac",
yearUTC.replaceFirst("0*", ""));
doc.addField(
searchFilter.getIndexFieldName()
+ "_ac",
value.replaceFirst("0*", ""));
doc.addField(
searchFilter.getIndexFieldName()
+ "_keyword",
value.replaceFirst("0*", ""));
}
//Also save a sort value of this year, this is required for determining the upper
// & lower bound year of our facet
if (doc.getField(indexField + "_sort") == null) {
//We can only add one year so take the first one
doc.addField(indexField + "_sort", yearUTC);
}
}
} else if (searchFilter.getType()
.equals(DiscoveryConfigurationParameters.TYPE_HIERARCHICAL)) {
HierarchicalSidebarFacetConfiguration hierarchicalSidebarFacetConfiguration =
(HierarchicalSidebarFacetConfiguration) searchFilter;
String[] subValues = value.split(hierarchicalSidebarFacetConfiguration.getSplitter());
if (hierarchicalSidebarFacetConfiguration
.isSkipFirstNodeLevel() && 1 < subValues.length) {
//Remove the first element of our array
subValues = (String[]) ArrayUtils.subarray(subValues, 1, subValues.length);
}
for (int i = 0; i < subValues.length; i++) {
StringBuilder valueBuilder = new StringBuilder();
for (int j = 0; j <= i; j++) {
valueBuilder.append(subValues[j]);
if (j < i) {
valueBuilder.append(hierarchicalSidebarFacetConfiguration.getSplitter());
}
}
String indexValue = valueBuilder.toString().trim();
doc.addField(searchFilter.getIndexFieldName() + "_tax_" + i + "_filter",
indexValue.toLowerCase() + separator + indexValue);
//We add the field x times that it has occurred
for (int j = i; j < subValues.length; j++) {
doc.addField(searchFilter.getIndexFieldName() + "_filter",
indexValue.toLowerCase() + separator + indexValue);
doc.addField(searchFilter.getIndexFieldName() + "_keyword", indexValue);
}
}
}
}
}
}
if ((sortFields.get(field) != null || recentSubmissionsConfigurationMap
.get(field) != null) && !sortFieldsAdded.contains(field)) {
//Only add sort value once
String type;
if (sortFields.get(field) != null) {
type = sortFields.get(field).getType();
} else {
type = recentSubmissionsConfigurationMap.get(field).getType();
}
if (type.equals(DiscoveryConfigurationParameters.TYPE_DATE)) {
Date date = MultiFormatDateParser.parse(value);
if (date != null) {
String stringDate = SolrUtils.getDateFormatter().format(date);
doc.addField(field + "_dt", stringDate);
} else {
log.warn("Error while indexing sort date field, item: " + item
.getHandle() + " metadata field: " + field + " date value: " + date);
}
} else {
doc.addField(field + "_sort", value);
}
sortFieldsAdded.add(field);
}
if (hitHighlightingFields.contains(field) || hitHighlightingFields
.contains("*") || hitHighlightingFields.contains(unqualifiedField + "." + Item.ANY)) {
if (authority != null) {
doc.addField(field + "_hl", value + SearchUtils.AUTHORITY_SEPARATOR + authority);
} else {
doc.addField(field + "_hl", value);
}
}
if (moreLikeThisFields.contains(field) || moreLikeThisFields
.contains(unqualifiedField + "." + Item.ANY)) {
doc.addField(field + "_mlt", value);
}
doc.addField(field, value);
if (authority != null) {
doc.addField(field + "_authority", authority);
}
if (toProjectionFields.contains(field) || toProjectionFields
.contains(unqualifiedField + "." + Item.ANY)) {
StringBuffer variantsToStore = new StringBuffer();
if (variants != null) {
for (String var : variants) {
variantsToStore.append(VARIANTS_STORE_SEPARATOR);
variantsToStore.append(var);
}
}
doc.addField(
field + "_stored",
value + STORE_SEPARATOR + preferedLabel
+ STORE_SEPARATOR
+ (variantsToStore.length() > VARIANTS_STORE_SEPARATOR
.length() ? variantsToStore
.substring(VARIANTS_STORE_SEPARATOR
.length()) : "null")
+ STORE_SEPARATOR + authority
+ STORE_SEPARATOR + meta.getLanguage());
}
if (meta.getLanguage() != null && !meta.getLanguage().trim().equals("")) {
String langField = field + "." + meta.getLanguage();
doc.addField(langField, value);
}
}
} catch (Exception e) {
log.error(LogManager.getHeader(context, "item_metadata_discovery_error",
"Item identifier: " + item.getID()), e);
}
log.debug(" Added Metadata");
try {
List<MetadataValue> values = itemService.getMetadataByMetadataString(item, "dc.relation.ispartof");
if (values != null && values.size() > 0 && values.get(0) != null && values.get(0).getValue() != null) {
// group on parent
String handlePrefix = handleService.getCanonicalPrefix();
doc.addField("publication_grp", values.get(0).getValue().replaceFirst(handlePrefix, ""));
} else {
// group on self
doc.addField("publication_grp", item.getHandle());
}
} catch (Exception e) {
log.error(LogManager.getHeader(context, "item_publication_group_discovery_error",
"Item identifier: " + item.getID()), e);
}
log.debug(" Added Grouping");
}
@Override
public void writeDocument(Context context, IndexableItem indexableObject, SolrInputDocument solrInputDocument)
throws SQLException, IOException, SolrServerException {
writeDocument(solrInputDocument, new FullTextContentStreams(context, indexableObject.getIndexedObject()));
}
@Override
public List<String> getLocations(Context context, IndexableItem indexableDSpaceObject)
throws SQLException {
final Item item = indexableDSpaceObject.getIndexedObject();
List<String> locations = new ArrayList<>();
// build list of community ids
List<Community> communities = itemService.getCommunities(context, item);
// build list of collection ids
List<Collection> collections = item.getCollections();
// now put those into strings
int i = 0;
for (i = 0; i < communities.size(); i++) {
locations.add("m" + communities.get(i).getID());
}
for (i = 0; i < collections.size(); i++) {
locations.add("l" + collections.get(i).getID());
}
return locations;
}
@Override
public void delete(IndexableItem indexableObject) throws IOException, SolrServerException {
super.delete(indexableObject);
deleteInProgressData(indexableObject.getUniqueIndexID());
}
private void deleteInProgressData(String indexableObjectIdentifier) throws SolrServerException, IOException {
// Also delete any possible workflowItem / workspaceItem / tasks related to this item
String query = "inprogress.item:\"" + indexableObjectIdentifier + "\"";
log.debug("Try to delete all in progress submission [DELETEBYQUERY]:" + query);
solrSearchCore.getSolr().deleteByQuery(query);
}
@Override
public void delete(String indexableObjectIdentifier) throws IOException, SolrServerException {
super.delete(indexableObjectIdentifier);
deleteInProgressData(indexableObjectIdentifier);
}
@Override
public boolean supports(Object object) {
return object instanceof Item;
}
@Override
public List getIndexableObjects(Context context, Item object) throws SQLException {
List<IndexableObject> results = new ArrayList<>();
if (object.isArchived() || object.isWithdrawn()) {
// We only want to index an item as an item if it is not in workflow
results.addAll(Arrays.asList(new IndexableItem(object)));
} else {
// Check if we have a workflow / workspace item
final WorkspaceItem workspaceItem = workspaceItemService.findByItem(context, object);
if (workspaceItem != null) {
results.addAll(workspaceItemIndexFactory.getIndexableObjects(context, workspaceItem));
} else {
// Check if we a workflow item
final XmlWorkflowItem xmlWorkflowItem = xmlWorkflowItemService.findByItem(context, object);
if (xmlWorkflowItem != null) {
results.addAll(workflowItemIndexFactory.getIndexableObjects(context, xmlWorkflowItem));
}
}
}
return results;
}
@Override
public Optional<IndexableItem> findIndexableObject(Context context, String id) throws SQLException {
final Item item = itemService.find(context, UUID.fromString(id));
return item == null ? Optional.empty() : Optional.of(new IndexableItem(item));
}
}

View File

@@ -0,0 +1,104 @@
/**
* 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.discovery.indexobject;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.common.SolrInputDocument;
import org.dspace.core.Context;
import org.dspace.discovery.indexobject.factory.PoolTaskIndexFactory;
import org.dspace.discovery.indexobject.factory.WorkflowItemIndexFactory;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.xmlworkflow.storedcomponents.PoolTask;
import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Factory implementation for indexing/retrieving pooled tasks in the search core
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class PoolTaskIndexFactoryImpl extends IndexFactoryImpl<IndexablePoolTask, PoolTask>
implements PoolTaskIndexFactory {
@Autowired
protected PoolTaskService poolTaskService;
@Autowired
WorkflowItemIndexFactory indexableWorkflowItemService;
@Override
public Iterator<IndexablePoolTask> findAll(Context context) throws SQLException {
final Iterator<PoolTask> pooledTasks = poolTaskService.findAll(context).iterator();
return new Iterator<IndexablePoolTask>() {
@Override
public boolean hasNext() {
return pooledTasks.hasNext();
}
@Override
public IndexablePoolTask next() {
return new IndexablePoolTask(pooledTasks.next());
}
};
}
@Override
public String getType() {
return IndexablePoolTask.TYPE;
}
@Override
public SolrInputDocument buildDocument(Context context, IndexablePoolTask indexableObject)
throws SQLException, IOException {
// Add the ID's, types and call the SolrServiceIndexPlugins
final SolrInputDocument doc = super.buildDocument(context, indexableObject);
final PoolTask poolTask = indexableObject.getIndexedObject();
// Add submitter, locations and modification time
indexableWorkflowItemService.storeInprogressItemFields(context, doc, poolTask.getWorkflowItem());
addFacetIndex(doc, "action", poolTask.getActionID(), poolTask.getActionID());
addFacetIndex(doc, "step", poolTask.getStepID(), poolTask.getStepID());
if (poolTask.getEperson() != null) {
doc.addField("taskfor", "e" + poolTask.getEperson().getID().toString());
}
if (poolTask.getGroup() != null) {
doc.addField("taskfor", "g" + poolTask.getGroup().getID().toString());
}
String acvalue = DSpaceServicesFactory.getInstance().getConfigurationService()
.getProperty("discovery.facet.namedtype.workflow.pooled");
if (StringUtils.isBlank(acvalue)) {
acvalue = indexableObject.getTypeText();
}
addNamedResourceTypeIndex(doc, acvalue);
return doc;
}
@Override
public boolean supports(Object object) {
return object instanceof PoolTask;
}
@Override
public List getIndexableObjects(Context context, PoolTask object) {
return Arrays.asList(new IndexablePoolTask(object));
}
@Override
public Optional<IndexablePoolTask> findIndexableObject(Context context, String id) throws SQLException {
final PoolTask poolTask = poolTaskService.find(context, Integer.parseInt(id));
return poolTask == null ? Optional.empty() : Optional.of(new IndexablePoolTask(poolTask));
}
}

View File

@@ -0,0 +1,121 @@
/**
* 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.discovery.indexobject;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.common.SolrInputDocument;
import org.dspace.content.Item;
import org.dspace.core.Context;
import org.dspace.discovery.IndexableObject;
import org.dspace.discovery.SearchUtils;
import org.dspace.discovery.configuration.DiscoveryConfiguration;
import org.dspace.discovery.indexobject.factory.WorkflowItemIndexFactory;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.xmlworkflow.storedcomponents.ClaimedTask;
import org.dspace.xmlworkflow.storedcomponents.PoolTask;
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService;
import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService;
import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Factory implementation for indexing/retrieving workflow items in the search core
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class WorkflowItemIndexFactoryImpl
extends InprogressSubmissionIndexFactoryImpl<IndexableWorkflowItem, XmlWorkflowItem>
implements WorkflowItemIndexFactory {
@Autowired
protected XmlWorkflowItemService workflowItemService;
@Autowired
protected ClaimedTaskService claimedTaskService;
@Autowired
protected PoolTaskService poolTaskService;
@Override
public Iterator<IndexableWorkflowItem> findAll(Context context) throws SQLException {
final Iterator<XmlWorkflowItem> workflowItems = workflowItemService.findAll(context).iterator();
return new Iterator<IndexableWorkflowItem>() {
@Override
public boolean hasNext() {
return workflowItems.hasNext();
}
@Override
public IndexableWorkflowItem next() {
return new IndexableWorkflowItem(workflowItems.next());
}
};
}
@Override
public String getType() {
return IndexableWorkflowItem.TYPE;
}
@Override
public SolrInputDocument buildDocument(Context context, IndexableWorkflowItem indexableObject)
throws SQLException, IOException {
// Add the ID's, types and call the SolrServiceIndexPlugins
final SolrInputDocument doc = super.buildDocument(context, indexableObject);
final XmlWorkflowItem workflowItem = indexableObject.getIndexedObject();
final Item item = workflowItem.getItem();
// Add the item metadata as configured
List<DiscoveryConfiguration> discoveryConfigurations = SearchUtils
.getAllDiscoveryConfigurations(workflowItem);
indexableItemService.addDiscoveryFields(doc, context, item, discoveryConfigurations);
String acvalue = DSpaceServicesFactory.getInstance().getConfigurationService()
.getProperty("discovery.facet.namedtype.workflow.item");
if (StringUtils.isBlank(acvalue)) {
acvalue = indexableObject.getTypeText();
}
addNamedResourceTypeIndex(doc, acvalue);
return doc;
}
@Override
public boolean supports(Object object) {
return object instanceof XmlWorkflowItem;
}
@Override
public List getIndexableObjects(Context context, XmlWorkflowItem object) throws SQLException {
List<IndexableObject> results = new ArrayList<>();
results.add(new IndexableWorkflowItem(object));
List<PoolTask> pools = poolTaskService.find(context, object);
for (PoolTask poolTask : pools) {
results.add(new IndexablePoolTask(poolTask));
}
List<ClaimedTask> claimedTasks = claimedTaskService.find(context, object);
for (ClaimedTask claimedTask : claimedTasks) {
results.add(new IndexableClaimedTask(claimedTask));
}
return results;
}
@Override
public Optional<IndexableWorkflowItem> findIndexableObject(Context context, String id) throws SQLException {
final XmlWorkflowItem xmlWorkflowItem = workflowItemService.find(context, Integer.parseInt(id));
return xmlWorkflowItem == null ? Optional.empty() : Optional.of(new IndexableWorkflowItem(xmlWorkflowItem));
}
}

View File

@@ -0,0 +1,99 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.discovery.indexobject;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.common.SolrInputDocument;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.WorkspaceItemService;
import org.dspace.core.Context;
import org.dspace.discovery.SearchUtils;
import org.dspace.discovery.configuration.DiscoveryConfiguration;
import org.dspace.discovery.indexobject.factory.WorkspaceItemIndexFactory;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Factory implementation for indexing/retrieving workspace items in the search core
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class WorkspaceItemIndexFactoryImpl
extends InprogressSubmissionIndexFactoryImpl<IndexableWorkspaceItem, WorkspaceItem>
implements WorkspaceItemIndexFactory {
@Autowired
protected WorkspaceItemService workspaceItemService;
@Override
public Iterator<IndexableWorkspaceItem> findAll(Context context) throws SQLException {
final Iterator<WorkspaceItem> workspaceItems = workspaceItemService.findAll(context).iterator();
return new Iterator<IndexableWorkspaceItem>() {
@Override
public boolean hasNext() {
return workspaceItems.hasNext();
}
@Override
public IndexableWorkspaceItem next() {
return new IndexableWorkspaceItem(workspaceItems.next());
}
};
}
@Override
public String getType() {
return IndexableWorkspaceItem.TYPE;
}
@Override
public SolrInputDocument buildDocument(Context context, IndexableWorkspaceItem indexableObject)
throws SQLException, IOException {
// Add the ID's, types and call the SolrServiceIndexPlugins
final SolrInputDocument doc = super.buildDocument(context, indexableObject);
// Add the object type
String acvalue = DSpaceServicesFactory.getInstance().getConfigurationService()
.getProperty("discovery.facet.namedtype.workspace");
if (StringUtils.isBlank(acvalue)) {
acvalue = indexableObject.getTypeText();
}
addNamedResourceTypeIndex(doc, acvalue);
final WorkspaceItem inProgressSubmission = indexableObject.getIndexedObject();
// Add the item metadata as configured
List<DiscoveryConfiguration> discoveryConfigurations = SearchUtils
.getAllDiscoveryConfigurations(inProgressSubmission);
indexableItemService.addDiscoveryFields(doc, context, inProgressSubmission.getItem(), discoveryConfigurations);
return doc;
}
@Override
public boolean supports(Object object) {
return object instanceof WorkspaceItem;
}
@Override
public List getIndexableObjects(Context context, WorkspaceItem object) {
return Arrays.asList(new IndexableWorkspaceItem(object));
}
@Override
public Optional<IndexableWorkspaceItem> findIndexableObject(Context context, String id) throws SQLException {
final WorkspaceItem workspaceItem = workspaceItemService.find(context, Integer.parseInt(id));
return workspaceItem == null ? Optional.empty() : Optional.of(new IndexableWorkspaceItem(workspaceItem));
}
}

View File

@@ -0,0 +1,19 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.discovery.indexobject.factory;
import org.dspace.discovery.indexobject.IndexableClaimedTask;
import org.dspace.xmlworkflow.storedcomponents.ClaimedTask;
/**
* Factory interface for indexing/retrieving claimed tasks in the search core
*
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public interface ClaimedTaskIndexFactory extends IndexFactory<IndexableClaimedTask, ClaimedTask> {
}

View File

@@ -0,0 +1,32 @@
/**
* 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.discovery.indexobject.factory;
import java.sql.SQLException;
import java.util.List;
import org.dspace.content.Collection;
import org.dspace.core.Context;
import org.dspace.discovery.indexobject.IndexableCollection;
/**
* Factory interface for indexing/retrieving collections in the search core
*
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public interface CollectionIndexFactory extends DSpaceObjectIndexFactory<IndexableCollection, Collection> {
/**
* Return a list of the identifiers of the owning communities from the provided collection prepended by "m"
* @param context DSpace context object
* @param collection DSpace collection
* @return A list of community identifiers with "m" prepended to every one
* @throws SQLException If database error
*/
public List<String> getCollectionLocations(Context context, Collection collection) throws SQLException;
}

View File

@@ -0,0 +1,19 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.discovery.indexobject.factory;
import org.dspace.content.Community;
import org.dspace.discovery.indexobject.IndexableCommunity;
/**
* Factory interface for indexing/retrieving communities in the search core
*
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public interface CommunityIndexFactory extends DSpaceObjectIndexFactory<IndexableCommunity, Community> {
}

View File

@@ -0,0 +1,42 @@
/**
* 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.discovery.indexobject.factory;
import java.sql.SQLException;
import java.util.List;
import org.apache.solr.common.SolrInputDocument;
import org.dspace.content.DSpaceObject;
import org.dspace.core.Context;
import org.dspace.discovery.indexobject.IndexableDSpaceObject;
/**
* Factory interface for indexing/retrieving DSpaceObjects in the search core
*
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public interface DSpaceObjectIndexFactory<T extends IndexableDSpaceObject, S extends DSpaceObject>
extends IndexFactory<T, S> {
/**
* Return a list of the identifiers from the parents for the provided IndexableObject,
* communities will be prepended by "m", collections b "c"
* @param context DSpace context object
* @return A list of community identifiers with "m" prepended to every one
* @throws SQLException If database error
*/
List<String> getLocations(Context context, T indexableDSpaceObject) throws SQLException;
/**
* Store the provided locations in the solr document
* @param doc The solr input document
* @param locations The locations to be stored
*/
void storeCommunityCollectionLocations(SolrInputDocument doc, List<String> locations);
}

View File

@@ -0,0 +1,108 @@
/**
* 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.discovery.indexobject.factory;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.common.SolrInputDocument;
import org.dspace.core.Context;
import org.dspace.discovery.IndexableObject;
/**
* Basis factory interface for indexing/retrieving any IndexableObject in the search core
*
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public interface IndexFactory<T extends IndexableObject, S> {
/**
* Retrieve all instances of a certain indexable object type
* @param context DSpace context object
* @return An iterator containing all the objects to be indexed for the indexable object
* @throws SQLException If database error
*/
Iterator<T> findAll(Context context) throws SQLException;
/**
* Return the type of the indexable object
* @return a string containing the type
*/
String getType();
/**
* Create solr document with all the shared fields initialized.
* @param indexableObject the indexableObject that we want to index
* @return initialized solr document
*/
SolrInputDocument buildDocument(Context context, T indexableObject) throws SQLException, IOException;
/**
* Write the provided document to the solr core
* @param context DSpace context object
* @param indexableObject The indexable object that we want to store in the search core
* @param solrInputDocument Solr input document which will be written to our discovery search core
* @throws SQLException If database error
* @throws IOException If IO error
* @throws SolrServerException If the solr document could not be written to the search core
*/
void writeDocument(Context context, T indexableObject, SolrInputDocument solrInputDocument)
throws SQLException, IOException, SolrServerException;
/**
* Remove the provided indexable object from the solr core
* @param indexableObject The indexable object that we want to remove from the search core
* @throws IOException If IO error
* @throws SolrServerException If the solr document could not be removed to the search core
*/
void delete(T indexableObject) throws IOException, SolrServerException;
/**
* Remove the provided indexable object from the solr core
* @param indexableObjectIdentifier The identifier that we want to remove from the search core
* @throws IOException If IO error
* @throws SolrServerException If the solr document could not be removed to the search core
*/
void delete(String indexableObjectIdentifier) throws IOException, SolrServerException;
/**
* Remove all indexable objects of the implementing type from the search core
* @throws IOException If IO error
* @throws SolrServerException If the solr document could not be removed to the search core
*/
void deleteAll() throws IOException, SolrServerException;
/**
* Retrieve a single indexable object using the provided identifier
* @param context DSpace context object
* @param id The identifier for which we want to retrieve our indexable object
* @return An indexable object
* @throws SQLException If database error
*/
Optional<T> findIndexableObject(Context context, String id) throws SQLException;
/**
* Determine whether the class can handle the factory implementation
* @param object The object which we want to check
* @return True if the factory implementation can handle the given object. False if it doesn't.
*/
boolean supports(Object object);
/**
* Retrieve all the indexable objects for the provided object
* @param context DSpace context object
* @param object The object we want to retrieve our indexable objects for
* @return A list of indexable objects
* @throws SQLException If database error
*/
List getIndexableObjects(Context context, S object) throws SQLException;
}

View File

@@ -0,0 +1,102 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.discovery.indexobject.factory;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.dspace.content.service.WorkspaceItemService;
import org.dspace.core.Context;
import org.dspace.discovery.IndexableObject;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.xmlworkflow.storedcomponents.service.ClaimedTaskService;
import org.dspace.xmlworkflow.storedcomponents.service.PoolTaskService;
import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Abstract factory to get the IndexFactory objects
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public abstract class IndexObjectFactoryFactory {
@Autowired
protected WorkspaceItemService workspaceItemService;
@Autowired
protected XmlWorkflowItemService xmlWorkflowItemService;
@Autowired
protected ClaimedTaskService claimedTaskService;
@Autowired
protected PoolTaskService poolTaskService;
/**
* Return the list of all the available implementations of the IndexableObjectService interface
*
* @return the list of IndexableObjectService
*/
public abstract List<IndexFactory> getIndexFactories();
/**
* Retrieve the IndexFactory implementation for the given indexable object
* @param indexableObject the indexable object for which we need our factory
* @return An IndexFactory implementation
*/
public IndexFactory getIndexableObjectFactory(IndexableObject indexableObject) {
return getIndexableObjectFactory(indexableObject.getType());
}
/**
* Retrieve the IndexFactory implementation for the given indexable object unique identifier
* @param indexableObjectUniqueString the unique identifier of an indexable object
* @return An IndexFactory implementation
*/
public IndexFactory getIndexableObjectFactory(String indexableObjectUniqueString) {
// The unique identifier of an IndexableObject will always be {type}-{identifier}
return getIndexFactoryByType(StringUtils.substringBefore(indexableObjectUniqueString, "-"));
}
/**
* Retrieve the IndexFactory implementation for the given indexable object type
* @param indexableFactoryType the object type of the indexable object
* @return An IndexFactory implementation
*/
public IndexFactory getIndexFactoryByType(String indexableFactoryType) {
for (IndexFactory indexableObjectFactory : getIndexFactories()) {
if (indexableObjectFactory.getType().equals(indexableFactoryType)) {
return indexableObjectFactory;
}
}
return null;
}
/**
* Retrieve all the indexable objects for the provided object
* @param context DSpace context object
* @param object The object we want to retrieve our indexable objects for
* @return A list of indexable objects
*/
public List<IndexableObject> getIndexableObjects(Context context, Object object) throws SQLException {
for (IndexFactory indexableObjectFactory : getIndexFactories()) {
if (indexableObjectFactory.supports(object)) {
return indexableObjectFactory.getIndexableObjects(context, object);
}
}
throw new IllegalArgumentException("The object: " + object.getClass().getName()
+ " cannot be indexed");
}
/**
* Retrieve an implementation instance for this factory
* @return an IndexObjectServiceFactory bean
*/
public static IndexObjectFactoryFactory getInstance() {
return DSpaceServicesFactory.getInstance().getServiceManager()
.getServiceByName("indexObjectFactoryFactory", IndexObjectFactoryFactory.class);
}
}

View File

@@ -0,0 +1,27 @@
/**
* 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.discovery.indexobject.factory;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Abstract factory implementation to get the IndexFactory objects
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public class IndexObjectFactoryFactoryImpl extends IndexObjectFactoryFactory {
@Autowired
List<IndexFactory> indexableObjectServices;
@Override
public List<IndexFactory> getIndexFactories() {
return indexableObjectServices;
}
}

View File

@@ -0,0 +1,35 @@
/**
* 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.discovery.indexobject.factory;
import java.sql.SQLException;
import org.apache.solr.common.SolrInputDocument;
import org.dspace.content.InProgressSubmission;
import org.dspace.core.Context;
import org.dspace.discovery.indexobject.IndexableInProgressSubmission;
/**
* Factory interface for indexing/retrieving InProgresssSubmission objects in the search core
*
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public interface InprogressSubmissionIndexFactory<T extends IndexableInProgressSubmission,
S extends InProgressSubmission>
extends IndexFactory<T, S> {
/**
* Store common fields between workspace / workflow items in the solr document
* @param context DSpace context object
* @param doc Solr input document which will be written to our discovery solr core
* @param inProgressSubmission the workspace / workflow item
* @throws SQLException If database error
*/
void storeInprogressItemFields(Context context, SolrInputDocument doc, InProgressSubmission inProgressSubmission)
throws SQLException;
}

View File

@@ -0,0 +1,41 @@
/**
* 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.discovery.indexobject.factory;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import org.apache.solr.common.SolrInputDocument;
import org.dspace.content.Item;
import org.dspace.core.Context;
import org.dspace.discovery.configuration.DiscoveryConfiguration;
import org.dspace.discovery.indexobject.IndexableItem;
/**
* Factory interface for indexing/retrieving items in the search core
*
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public interface ItemIndexFactory extends DSpaceObjectIndexFactory<IndexableItem, Item> {
/**
* Store item fields in the solr document
* @param doc Solr input document which will be written to our discovery solr core
* @param context DSpace context object
* @param item Item for which we want to index our fields in the provided solr document
* @param discoveryConfigurations The discovery configuration which holds information
* for which item fields we should index
* @throws SQLException If database error
* @throws IOException If IO error
*/
void addDiscoveryFields(SolrInputDocument doc, Context context, Item item,
List<DiscoveryConfiguration> discoveryConfigurations)
throws SQLException, IOException;
}

View File

@@ -0,0 +1,19 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.discovery.indexobject.factory;
import org.dspace.discovery.indexobject.IndexablePoolTask;
import org.dspace.xmlworkflow.storedcomponents.PoolTask;
/**
* Factory interface for indexing/retrieving Pooltask objects in the search core
*
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public interface PoolTaskIndexFactory extends IndexFactory<IndexablePoolTask, PoolTask> {
}

View File

@@ -0,0 +1,20 @@
/**
* 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.discovery.indexobject.factory;
import org.dspace.discovery.indexobject.IndexableWorkflowItem;
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
/**
* Factory interface for indexing/retrieving workflow items objects in the search core
*
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public interface WorkflowItemIndexFactory
extends InprogressSubmissionIndexFactory<IndexableWorkflowItem, XmlWorkflowItem> {
}

View File

@@ -0,0 +1,20 @@
/**
* 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.discovery.indexobject.factory;
import org.dspace.content.WorkspaceItem;
import org.dspace.discovery.indexobject.IndexableWorkspaceItem;
/**
* Factory interface for indexing/retrieving workspace item objects in the search core
*
* @author Kevin Van de Velde (kevin at atmire dot com)
*/
public interface WorkspaceItemIndexFactory
extends InprogressSubmissionIndexFactory<IndexableWorkspaceItem, WorkspaceItem> {
}

View File

@@ -31,6 +31,8 @@ import org.dspace.discovery.DiscoverResult;
import org.dspace.discovery.IndexableObject;
import org.dspace.discovery.SearchServiceException;
import org.dspace.discovery.SearchUtils;
import org.dspace.discovery.indexobject.IndexableDSpaceObject;
import org.dspace.discovery.indexobject.IndexableItem;
import org.dspace.eperson.Group;
import org.dspace.handle.factory.HandleServiceFactory;
import org.dspace.handle.service.HandleService;
@@ -97,7 +99,7 @@ public class Harvest {
boolean items, boolean collections, boolean withdrawn,
boolean nonAnon) throws SQLException, ParseException {
DiscoverQuery discoverQuery = new DiscoverQuery();
discoverQuery.addFilterQueries("search.resourcetype:" + Constants.ITEM);
discoverQuery.addFilterQueries("search.resourcetype:" + IndexableItem.TYPE);
if (scope != null) {
if (scope instanceof Community) {
@@ -143,13 +145,13 @@ public class Harvest {
Iterator<IndexableObject> dsoIterator = discoverResult.getIndexableObjects().iterator();
while (dsoIterator.hasNext() && ((limit == 0) || (itemCounter < limit))) {
// the query is limited to ITEM
DSpaceObject dso = (DSpaceObject) dsoIterator.next();
IndexableDSpaceObject indexableDSpaceObject = (IndexableDSpaceObject) dsoIterator.next();
HarvestedItemInfo itemInfo = new HarvestedItemInfo();
itemInfo.context = context;
itemInfo.handle = dso.getHandle();
itemInfo.itemID = dso.getID();
itemInfo.datestamp = ((Item) dso).getLastModified();
itemInfo.withdrawn = ((Item) dso).isWithdrawn();
itemInfo.handle = indexableDSpaceObject.getIndexedObject().getHandle();
itemInfo.itemID = indexableDSpaceObject.getID();
itemInfo.datestamp = ((IndexableItem) indexableDSpaceObject).getIndexedObject().getLastModified();
itemInfo.withdrawn = ((IndexableItem) indexableDSpaceObject).getIndexedObject().isWithdrawn();
if (collections) {
// Add collections data

View File

@@ -8,13 +8,12 @@
package org.dspace.workflow;
import org.dspace.content.InProgressSubmission;
import org.dspace.core.ReloadableEntity;
/**
* Interface representing a workflowitem, each workflowItem implementation must implement this interface.
*
* @author kevinvandevelde at atmire.com
*/
public interface WorkflowItem extends InProgressSubmission<Integer>, ReloadableEntity<Integer> {
public interface WorkflowItem extends InProgressSubmission {
public int getState();
}

View File

@@ -26,7 +26,7 @@ import org.dspace.eperson.EPerson;
*
* @author kevinvandevelde at atmire.com
*/
public interface WorkflowItemService<T extends WorkflowItem> extends InProgressSubmissionService<T, Integer> {
public interface WorkflowItemService<T extends WorkflowItem> extends InProgressSubmissionService<T> {
public T create(Context context, Item item, Collection collection) throws SQLException, AuthorizeException;

View File

@@ -7,8 +7,6 @@
*/
package org.dspace.workflowbasic;
import java.sql.SQLException;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
@@ -23,7 +21,6 @@ import javax.persistence.Table;
import org.dspace.content.Collection;
import org.dspace.content.Item;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.workflow.WorkflowItem;
@@ -152,7 +149,7 @@ public class BasicWorkflowItem implements WorkflowItem {
}
@Override
public EPerson getSubmitter() throws SQLException {
public EPerson getSubmitter() {
return item.getSubmitter();
}
@@ -185,10 +182,4 @@ public class BasicWorkflowItem implements WorkflowItem {
public void setPublishedBefore(boolean b) {
this.publishedBefore = b;
}
@Override
public int getType() {
return Constants.WORKFLOWITEM;
}
}

View File

@@ -17,7 +17,6 @@ import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Collection;
import org.dspace.content.Item;
import org.dspace.content.service.ItemService;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.dspace.eperson.EPerson;
@@ -53,11 +52,6 @@ public class BasicWorkflowItemServiceImpl implements BasicWorkflowItemService {
}
@Override
public int getSupportsIndexableObjectTypeConstant() {
return Constants.WORKFLOWITEM;
}
@Override
public BasicWorkflowItem create(Context context, Item item, Collection collection)
throws SQLException, AuthorizeException {
@@ -90,14 +84,6 @@ public class BasicWorkflowItemServiceImpl implements BasicWorkflowItemService {
return workflowItem;
}
@Override
public BasicWorkflowItem findIndexableObject(Context context, Integer id) throws SQLException {
if (id != null) {
return find(context, id);
}
return null;
}
@Override
public List<BasicWorkflowItem> findAll(Context context) throws SQLException {
return workflowItemDAO.findAll(context, BasicWorkflowItem.class);

View File

@@ -18,10 +18,8 @@ import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.ReloadableEntity;
import org.dspace.discovery.IndexableObject;
import org.dspace.eperson.EPerson;
/**
@@ -34,7 +32,7 @@ import org.dspace.eperson.EPerson;
*/
@Entity
@Table(name = "cwf_claimtask")
public class ClaimedTask implements ReloadableEntity<Integer>, IndexableObject<Integer> {
public class ClaimedTask implements ReloadableEntity<Integer> {
@Id
@Column(name = "claimtask_id")
@@ -116,10 +114,4 @@ public class ClaimedTask implements ReloadableEntity<Integer>, IndexableObject<I
public String getWorkflowID() {
return workflowId;
}
@Override
public int getType() {
return Constants.CLAIMEDTASK;
}
}

View File

@@ -14,7 +14,6 @@ import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.xmlworkflow.storedcomponents.dao.ClaimedTaskDAO;
@@ -37,11 +36,6 @@ public class ClaimedTaskServiceImpl implements ClaimedTaskService {
}
@Override
public int getSupportsIndexableObjectTypeConstant() {
return Constants.CLAIMEDTASK;
}
@Override
public ClaimedTask create(Context context) throws SQLException, AuthorizeException {
return claimedTaskDAO.create(context, new ClaimedTask());
@@ -53,11 +47,8 @@ public class ClaimedTaskServiceImpl implements ClaimedTaskService {
}
@Override
public ClaimedTask findIndexableObject(Context context, Integer id) throws SQLException {
if (id == null) {
return null;
}
return find(context, id.intValue());
public List<ClaimedTask> findAll(Context context) throws SQLException {
return claimedTaskDAO.findAll(context, ClaimedTask.class);
}
@Override

View File

@@ -19,10 +19,8 @@ import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.ReloadableEntity;
import org.dspace.discovery.IndexableObject;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
@@ -36,7 +34,7 @@ import org.dspace.eperson.Group;
*/
@Entity
@Table(name = "cwf_pooltask")
public class PoolTask implements ReloadableEntity<Integer>, IndexableObject<Integer> {
public class PoolTask implements ReloadableEntity<Integer> {
@Id
@Column(name = "pooltask_id")
@@ -131,10 +129,4 @@ public class PoolTask implements ReloadableEntity<Integer>, IndexableObject<Inte
public String getActionID() {
return this.actionId;
}
@Override
public int getType() {
return Constants.POOLTASK;
}
}

View File

@@ -17,7 +17,6 @@ import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
@@ -49,8 +48,8 @@ public class PoolTaskServiceImpl implements PoolTaskService {
}
@Override
public int getSupportsIndexableObjectTypeConstant() {
return Constants.POOLTASK;
public List<PoolTask> findAll(Context context) throws SQLException {
return poolTaskDAO.findAll(context, PoolTask.class);
}
@Override
@@ -141,14 +140,6 @@ public class PoolTaskServiceImpl implements PoolTaskService {
return poolTaskDAO.findByID(context, PoolTask.class, id);
}
@Override
public PoolTask findIndexableObject(Context context, Integer id) throws SQLException {
if (id == null) {
return null;
}
return find(context, id.intValue());
}
@Override
public void update(Context context, PoolTask poolTask) throws SQLException, AuthorizeException {
update(context, Collections.singletonList(poolTask));

View File

@@ -7,8 +7,6 @@
*/
package org.dspace.xmlworkflow.storedcomponents;
import java.sql.SQLException;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
@@ -23,10 +21,7 @@ import javax.persistence.Table;
import org.dspace.content.Collection;
import org.dspace.content.Item;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.ReloadableEntity;
import org.dspace.discovery.IndexableObject;
import org.dspace.eperson.EPerson;
import org.dspace.workflow.WorkflowItem;
@@ -40,7 +35,7 @@ import org.dspace.workflow.WorkflowItem;
*/
@Entity
@Table(name = "cwf_workflowitem")
public class XmlWorkflowItem implements WorkflowItem, ReloadableEntity<Integer>, IndexableObject<Integer> {
public class XmlWorkflowItem implements WorkflowItem {
@Id
@Column(name = "workflowitem_id")
@@ -103,7 +98,7 @@ public class XmlWorkflowItem implements WorkflowItem, ReloadableEntity<Integer>,
}
@Override
public EPerson getSubmitter() throws SQLException {
public EPerson getSubmitter() {
return item.getSubmitter();
}
@@ -143,10 +138,4 @@ public class XmlWorkflowItem implements WorkflowItem, ReloadableEntity<Integer>,
// simplified
return 0;
}
@Override
public int getType() {
return Constants.WORKFLOWITEM;
}
}

View File

@@ -17,7 +17,6 @@ import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Collection;
import org.dspace.content.Item;
import org.dspace.content.service.ItemService;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.dspace.eperson.EPerson;
@@ -63,11 +62,6 @@ public class XmlWorkflowItemServiceImpl implements XmlWorkflowItemService {
}
@Override
public int getSupportsIndexableObjectTypeConstant() {
return Constants.WORKFLOWITEM;
}
@Override
public XmlWorkflowItem create(Context context, Item item, Collection collection)
throws SQLException, AuthorizeException {
@@ -95,14 +89,6 @@ public class XmlWorkflowItemServiceImpl implements XmlWorkflowItemService {
return workflowItem;
}
@Override
public XmlWorkflowItem findIndexableObject(Context context, Integer id) throws SQLException {
if (id != null) {
return find(context, id);
}
return null;
}
@Override
public List<XmlWorkflowItem> findAll(Context context) throws SQLException {
return xmlWorkflowItemDAO.findAll(context, XmlWorkflowItem.class);

View File

@@ -11,7 +11,6 @@ import java.sql.SQLException;
import java.util.List;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.service.IndexableObjectService;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.service.DSpaceCRUDService;
@@ -25,8 +24,7 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
*
* @author kevinvandevelde at atmire.com
*/
public interface ClaimedTaskService extends DSpaceCRUDService<ClaimedTask>,
IndexableObjectService<ClaimedTask, Integer> {
public interface ClaimedTaskService extends DSpaceCRUDService<ClaimedTask> {
public List<ClaimedTask> findByWorkflowItem(Context context, XmlWorkflowItem workflowItem) throws SQLException;
@@ -49,4 +47,6 @@ public interface ClaimedTaskService extends DSpaceCRUDService<ClaimedTask>,
public void deleteByWorkflowItem(Context context, XmlWorkflowItem workflowItem)
throws SQLException, AuthorizeException;
List<ClaimedTask> findAll(Context context) throws SQLException;
}

View File

@@ -12,7 +12,6 @@ import java.sql.SQLException;
import java.util.List;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.service.IndexableObjectService;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.service.DSpaceCRUDService;
@@ -26,7 +25,10 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
*
* @author kevinvandevelde at atmire.com
*/
public interface PoolTaskService extends DSpaceCRUDService<PoolTask>, IndexableObjectService<PoolTask, Integer> {
public interface PoolTaskService extends DSpaceCRUDService<PoolTask> {
public List<PoolTask> findAll(Context context) throws SQLException;
public List<PoolTask> findByEperson(Context context, EPerson ePerson)
throws SQLException, AuthorizeException, IOException;

View File

@@ -19,7 +19,7 @@
<context:annotation-config/> <!-- allows us to use spring annotations in beans -->
<bean class="org.dspace.discovery.MockSolrServiceImpl" id="org.dspace.discovery.SearchService"/>
<bean class="org.dspace.discovery.SolrServiceImpl" id="org.dspace.discovery.SearchService"/>
<alias name="org.dspace.discovery.SearchService" alias="org.dspace.discovery.IndexingService"/>
@@ -27,6 +27,8 @@
<bean class="org.dspace.authority.MockAuthoritySolrServiceImpl" id="org.dspace.authority.AuthoritySearchService"/>
<alias name="org.dspace.authority.AuthoritySearchService" alias="org.dspace.authority.indexer.AuthorityIndexingService"/>
<bean id="org.dspace.discovery.SolrSearchCore" class="org.dspace.discovery.MockSolrSearchCore" autowire-candidate="true"/>
<!--<bean class="org.dspace.discovery.SolrServiceIndexOutputPlugin" id="solrServiceIndexOutputPlugin"/>-->
<!-- Statistics services are both lazy loaded (by name), as you are likely just using ONE of them and not both -->

View File

@@ -14,7 +14,7 @@ import org.springframework.stereotype.Service;
* Mock SOLR service for the Search Core
*/
@Service
public class MockSolrServiceImpl extends SolrServiceImpl implements InitializingBean {
public class MockSolrSearchCore extends SolrSearchCore implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {

View File

@@ -12,7 +12,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -112,7 +111,7 @@ public class OpenSearchController {
}
// then the rest - we are processing the query
IndexableObject<UUID> container = null;
IndexableObject container = null;
// support pagination parameters
DiscoverQuery queryArgs = new DiscoverQuery();

View File

@@ -7,8 +7,6 @@
*/
package org.dspace.app.rest.converter;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
@@ -38,11 +36,9 @@ import org.springframework.beans.factory.annotation.Autowired;
* the DSpace API inprogressSubmission object
* @param <R>
* the DSpace REST inprogressSubmission representation
* @param <ID>
* the Serializable class used as primary key
*/
public abstract class AInprogressItemConverter<T extends InProgressSubmission<ID>,
R extends AInprogressSubmissionRest<ID>, ID extends Serializable>
public abstract class AInprogressItemConverter<T extends InProgressSubmission,
R extends AInprogressSubmissionRest>
implements IndexableObjectConverter<T, R> {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(AInprogressItemConverter.class);
@@ -66,11 +62,7 @@ public abstract class AInprogressItemConverter<T extends InProgressSubmission<ID
Collection collection = obj.getCollection();
Item item = obj.getItem();
EPerson submitter = null;
try {
submitter = obj.getSubmitter();
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
submitter = obj.getSubmitter();
witem.setId(obj.getID());
witem.setCollection(collection != null ? converter.toRest(collection, projection) : null);

View File

@@ -47,8 +47,7 @@ public class ClaimedTaskConverter
}
@Override
public boolean supportsModel(IndexableObject object) {
return object instanceof ClaimedTask;
public boolean supportsModel(IndexableObject idxo) {
return idxo.getIndexedObject() instanceof ClaimedTask;
}
}

View File

@@ -109,6 +109,6 @@ public class CollectionConverter
@Override
public boolean supportsModel(IndexableObject idxo) {
return idxo instanceof Collection;
return idxo.getIndexedObject() instanceof Collection;
}
}

View File

@@ -75,6 +75,6 @@ public class CommunityConverter
@Override
public boolean supportsModel(IndexableObject idxo) {
return idxo instanceof Community;
return idxo.getIndexedObject() instanceof Community;
}
}

View File

@@ -91,10 +91,11 @@ public class DiscoverResultConverter {
}
}
private RestAddressableModel convertDSpaceObject(final IndexableObject dspaceObject, final Projection projection) {
for (IndexableObjectConverter<IndexableObject, RestAddressableModel> converter : converters) {
if (converter.supportsModel(dspaceObject)) {
return converter.convert(dspaceObject, projection);
private RestAddressableModel convertDSpaceObject(final IndexableObject indexableObject,
final Projection projection) {
for (IndexableObjectConverter<Object, RestAddressableModel> converter : converters) {
if (converter.supportsModel(indexableObject)) {
return converter.convert(indexableObject.getIndexedObject(), projection);
}
}
return null;

View File

@@ -17,11 +17,11 @@ import org.dspace.discovery.IndexableObject;
* @param <R> the Class in the DSpace REST data model
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
public interface IndexableObjectConverter<M extends IndexableObject,
public interface IndexableObjectConverter<M,
R extends org.dspace.app.rest.model.RestAddressableModel> extends DSpaceConverter<M, R> {
/**
*
*
* @param idxo
* the IndexableObject to check
* @return true if the actual converter implementation is able to manage the supplied IndexableObject

View File

@@ -82,6 +82,6 @@ public class ItemConverter
@Override
public boolean supportsModel(IndexableObject idxo) {
return idxo instanceof Item;
return idxo.getIndexedObject() instanceof Item;
}
}

View File

@@ -53,8 +53,7 @@ public class PoolTaskConverter
}
@Override
public boolean supportsModel(IndexableObject object) {
return object instanceof PoolTask;
public boolean supportsModel(IndexableObject idxo) {
return idxo.getIndexedObject() instanceof PoolTask;
}
}

View File

@@ -23,7 +23,7 @@ import org.springframework.stereotype.Component;
*/
@Component
public class WorkflowItemConverter
extends AInprogressItemConverter<XmlWorkflowItem, org.dspace.app.rest.model.WorkflowItemRest, Integer> {
extends AInprogressItemConverter<XmlWorkflowItem, org.dspace.app.rest.model.WorkflowItemRest> {
public WorkflowItemConverter() throws SubmissionConfigReaderException {
super();
@@ -44,6 +44,6 @@ public class WorkflowItemConverter
@Override
public boolean supportsModel(IndexableObject object) {
return object instanceof XmlWorkflowItem;
return object.getIndexedObject() instanceof XmlWorkflowItem;
}
}

View File

@@ -22,7 +22,7 @@ import org.springframework.stereotype.Component;
*/
@Component
public class WorkspaceItemConverter
extends AInprogressItemConverter<WorkspaceItem, WorkspaceItemRest, Integer> {
extends AInprogressItemConverter<WorkspaceItem, WorkspaceItemRest> {
public WorkspaceItemConverter() throws SubmissionConfigReaderException {
super();
@@ -47,6 +47,6 @@ public class WorkspaceItemConverter
@Override
public boolean supportsModel(IndexableObject object) {
return object instanceof WorkspaceItem;
return object.getIndexedObject() instanceof WorkspaceItem;
}
}

View File

@@ -19,10 +19,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*
* @param <T>
* the serializable class used as primary key
*/
public abstract class AInprogressSubmissionRest<T extends Serializable> extends BaseObjectRest<T> {
public abstract class AInprogressSubmissionRest extends BaseObjectRest<Integer> {
private Date lastModified = new Date();
private Map<String, Serializable> sections;

View File

@@ -14,7 +14,7 @@ import org.dspace.app.rest.RestResourceController;
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
public class WorkflowItemRest extends AInprogressSubmissionRest<Integer> {
public class WorkflowItemRest extends AInprogressSubmissionRest {
public static final String NAME = "workflowitem";
public static final String CATEGORY = RestAddressableModel.WORKFLOW;

View File

@@ -14,7 +14,7 @@ import org.dspace.app.rest.RestResourceController;
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/
public class WorkspaceItemRest extends AInprogressSubmissionRest<Integer> {
public class WorkspaceItemRest extends AInprogressSubmissionRest {
public static final String NAME = "workspaceitem";
public static final String CATEGORY = RestAddressableModel.SUBMISSION;

View File

@@ -145,8 +145,8 @@ public class BrowseItemLinkRepository extends AbstractDSpaceRestRepository
Pageable pageResultInfo =
new PageRequest((binfo.getStart() - 1) / binfo.getResultsPerPage(), binfo.getResultsPerPage());
List<Item> tmpResult = new ArrayList<Item>();
for (IndexableObject bb : binfo.getBrowseItemResults()) {
tmpResult.add((Item) bb);
for (Item bb : binfo.getBrowseItemResults()) {
tmpResult.add(bb);
}
return converter.toRestPage(tmpResult, pageResultInfo, binfo.getTotal(), projection);

View File

@@ -10,8 +10,9 @@ package org.dspace.app.rest.security;
import java.io.Serializable;
import java.sql.SQLException;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.ClaimedTaskRest;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.service.EPersonService;
@@ -49,7 +50,7 @@ public class ClaimedTaskRestPermissionEvaluatorPlugin extends RestObjectPermissi
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId,
String targetType, DSpaceRestPermission permission) {
if (Constants.getTypeID(targetType) != Constants.CLAIMEDTASK) {
if (!StringUtils.equalsIgnoreCase(ClaimedTaskRest.NAME, targetType)) {
return false;
}

View File

@@ -11,9 +11,10 @@ import java.io.IOException;
import java.io.Serializable;
import java.sql.SQLException;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.PoolTaskRest;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.service.EPersonService;
@@ -51,7 +52,7 @@ public class PoolTaskRestPermissionEvaluatorPlugin extends RestObjectPermissionE
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId,
String targetType, DSpaceRestPermission permission) {
if (Constants.getTypeID(targetType) != Constants.POOLTASK) {
if (!StringUtils.equalsIgnoreCase(PoolTaskRest.NAME, targetType)) {
return false;
}

Some files were not shown because too many files have changed in this diff Show More