Fix Merge conflicts with main

This commit is contained in:
frabacche
2024-01-04 16:21:40 +01:00
62 changed files with 566 additions and 294 deletions

View File

@@ -77,7 +77,7 @@ import org.dspace.orcid.service.OrcidQueueService;
import org.dspace.orcid.service.OrcidSynchronizationService;
import org.dspace.orcid.service.OrcidTokenService;
import org.dspace.profile.service.ResearcherProfileService;
import org.dspace.qaevent.dao.QAEventsDao;
import org.dspace.qaevent.dao.QAEventsDAO;
import org.dspace.services.ConfigurationService;
import org.dspace.versioning.service.VersioningService;
import org.dspace.workflow.WorkflowItemService;
@@ -172,7 +172,7 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
protected SubscribeService subscribeService;
@Autowired
private QAEventsDao qaEventsDao;
private QAEventsDAO qaEventsDao;
protected ItemServiceImpl() {
super();

View File

@@ -37,9 +37,17 @@ public class QAEvent {
private String source;
private String eventId;
/**
* contains the targeted dspace object,
* ie: oai:www.openstarts.units.it:123456789/1120 contains the handle
* of the DSpace pbject in its final part 123456789/1120
* */
private String originalId;
/**
* evaluated with the targeted dspace object id
*
* */
private String target;
private String related;

View File

@@ -48,7 +48,7 @@ import org.dspace.eperson.service.GroupService;
import org.dspace.eperson.service.SubscribeService;
import org.dspace.event.Event;
import org.dspace.orcid.service.OrcidTokenService;
import org.dspace.qaevent.dao.QAEventsDao;
import org.dspace.qaevent.dao.QAEventsDAO;
import org.dspace.services.ConfigurationService;
import org.dspace.util.UUIDUtils;
import org.dspace.versioning.Version;
@@ -109,7 +109,7 @@ public class EPersonServiceImpl extends DSpaceObjectServiceImpl<EPerson> impleme
@Autowired
protected OrcidTokenService orcidTokenService;
@Autowired
protected QAEventsDao qaEventsDao;
protected QAEventsDAO qaEventsDao;
protected EPersonServiceImpl() {
super();

View File

@@ -40,20 +40,20 @@ import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
/**
* based on OrcidRestConnector it's a rest connector for OpenAIRE API providing
* based on OrcidRestConnector it's a rest connector for Openaire API providing
* ways to perform searches and token grabbing
*
* @author paulo-graca
*
*/
public class OpenAIRERestConnector {
public class OpenaireRestConnector {
/**
* log4j logger
*/
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(OpenAIRERestConnector.class);
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(OpenaireRestConnector.class);
/**
* OpenAIRE API Url
* Openaire API Url
* and can be configured with: openaire.api.url
*/
private String url = "https://api.openaire.eu";
@@ -65,30 +65,30 @@ public class OpenAIRERestConnector {
boolean tokenEnabled = false;
/**
* OpenAIRE Authorization and Authentication Token Service URL
* Openaire Authorization and Authentication Token Service URL
* and can be configured with: openaire.token.url
*/
private String tokenServiceUrl;
/**
* OpenAIRE clientId
* Openaire clientId
* and can be configured with: openaire.token.clientId
*/
private String clientId;
/**
* OpenAIRERest access token
* OpenaireRest access token
*/
private OpenAIRERestToken accessToken;
private OpenaireRestToken accessToken;
/**
* OpenAIRE clientSecret
* Openaire clientSecret
* and can be configured with: openaire.token.clientSecret
*/
private String clientSecret;
public OpenAIRERestConnector(String url) {
public OpenaireRestConnector(String url) {
this.url = url;
}
@@ -99,7 +99,7 @@ public class OpenAIRERestConnector {
*
* @throws IOException
*/
public OpenAIRERestToken grabNewAccessToken() throws IOException {
public OpenaireRestToken grabNewAccessToken() throws IOException {
if (StringUtils.isBlank(tokenServiceUrl) || StringUtils.isBlank(clientId)
|| StringUtils.isBlank(clientSecret)) {
@@ -145,13 +145,13 @@ public class OpenAIRERestConnector {
throw new IOException("Unable to grab the access token using provided service url, client id and secret");
}
return new OpenAIRERestToken(responseObject.get("access_token").toString(),
return new OpenaireRestToken(responseObject.get("access_token").toString(),
Long.valueOf(responseObject.get("expires_in").toString()));
}
/**
* Perform a GET request to the OpenAIRE API
* Perform a GET request to the Openaire API
*
* @param file
* @param accessToken
@@ -218,12 +218,12 @@ public class OpenAIRERestConnector {
}
/**
* Perform an OpenAIRE Project Search By Keywords
* Perform an Openaire Project Search By Keywords
*
* @param page
* @param size
* @param keywords
* @return OpenAIRE Response
* @return Openaire Response
*/
public Response searchProjectByKeywords(int page, int size, String... keywords) {
String path = "search/projects?keywords=" + String.join("+", keywords);
@@ -231,13 +231,13 @@ public class OpenAIRERestConnector {
}
/**
* Perform an OpenAIRE Project Search By ID and by Funder
* Perform an Openaire Project Search By ID and by Funder
*
* @param projectID
* @param projectFunder
* @param page
* @param size
* @return OpenAIRE Response
* @return Openaire Response
*/
public Response searchProjectByIDAndFunder(String projectID, String projectFunder, int page, int size) {
String path = "search/projects?grantID=" + projectID + "&funder=" + projectFunder;
@@ -245,12 +245,12 @@ public class OpenAIRERestConnector {
}
/**
* Perform an OpenAIRE Search request
* Perform an Openaire Search request
*
* @param path
* @param page
* @param size
* @return OpenAIRE Response
* @return Openaire Response
*/
public Response search(String path, int page, int size) {
String[] queryStringPagination = { "page=" + page, "size=" + size };

View File

@@ -8,13 +8,13 @@
package org.dspace.external;
/**
* OpenAIRE rest API token to be used when grabbing an accessToken.<br/>
* Openaire rest API token to be used when grabbing an accessToken.<br/>
* Based on https://develop.openaire.eu/basic.html
*
* @author paulo-graca
*
*/
public class OpenAIRERestToken {
public class OpenaireRestToken {
/**
* Stored access token
@@ -32,7 +32,7 @@ public class OpenAIRERestToken {
* @param accessToken
* @param expiresIn
*/
public OpenAIRERestToken(String accessToken, Long expiresIn) {
public OpenaireRestToken(String accessToken, Long expiresIn) {
this.accessToken = accessToken;
this.setExpirationDate(expiresIn);
}

View File

@@ -31,7 +31,7 @@ import eu.openaire.oaf.model.base.Project;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.dspace.content.dto.MetadataValueDTO;
import org.dspace.external.OpenAIRERestConnector;
import org.dspace.external.OpenaireRestConnector;
import org.dspace.external.model.ExternalDataObject;
import org.dspace.external.provider.AbstractExternalDataProvider;
import org.dspace.importer.external.metadatamapping.MetadataFieldConfig;
@@ -39,13 +39,13 @@ import org.springframework.beans.factory.annotation.Autowired;
/**
* This class is the implementation of the ExternalDataProvider interface that
* will deal with the OpenAIRE External Data lookup
* will deal with the Openaire External Data lookup
*
* @author paulo-graca
*/
public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider {
public class OpenaireFundingDataProvider extends AbstractExternalDataProvider {
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(OpenAIREFundingDataProvider.class);
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(OpenaireFundingDataProvider.class);
/**
* GrantAgreement prefix
@@ -75,7 +75,7 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider {
/**
* Connector to handle token and requests
*/
protected OpenAIRERestConnector connector;
protected OpenaireRestConnector connector;
protected Map<String, MetadataFieldConfig> metadataFields;
@@ -93,7 +93,7 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider {
// characters that must be escaped for the <:entry-id>
String decodedId = new String(Base64.getDecoder().decode(id));
if (!isValidProjectURI(decodedId)) {
log.error("Invalid ID for OpenAIREFunding - " + id);
log.error("Invalid ID for OpenaireFunding - " + id);
return Optional.empty();
}
Response response = searchByProjectURI(decodedId);
@@ -101,7 +101,7 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider {
try {
if (response.getHeader() != null && Integer.parseInt(response.getHeader().getTotal()) > 0) {
Project project = response.getResults().getResult().get(0).getMetadata().getEntity().getProject();
ExternalDataObject externalDataObject = new OpenAIREFundingDataProvider
ExternalDataObject externalDataObject = new OpenaireFundingDataProvider
.ExternalDataObjectBuilder(project)
.setId(generateProjectURI(project))
.setSource(sourceIdentifier)
@@ -123,7 +123,7 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider {
limit = LIMIT_DEFAULT;
}
// OpenAIRE uses pages and first page starts with 1
// Openaire uses pages and first page starts with 1
int page = (start / limit) + 1;
// escaping query
@@ -148,7 +148,7 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider {
if (projects.size() > 0) {
return projects.stream()
.map(project -> new OpenAIREFundingDataProvider
.map(project -> new OpenaireFundingDataProvider
.ExternalDataObjectBuilder(project)
.setId(generateProjectURI(project))
.setSource(sourceIdentifier)
@@ -176,24 +176,24 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider {
* Generic setter for the sourceIdentifier
*
* @param sourceIdentifier The sourceIdentifier to be set on this
* OpenAIREFunderDataProvider
* OpenaireFunderDataProvider
*/
@Autowired(required = true)
public void setSourceIdentifier(String sourceIdentifier) {
this.sourceIdentifier = sourceIdentifier;
}
public OpenAIRERestConnector getConnector() {
public OpenaireRestConnector getConnector() {
return connector;
}
/**
* Generic setter for OpenAIRERestConnector
* Generic setter for OpenaireRestConnector
*
* @param connector
*/
@Autowired(required = true)
public void setConnector(OpenAIRERestConnector connector) {
public void setConnector(OpenaireRestConnector connector) {
this.connector = connector;
}
@@ -219,7 +219,7 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider {
}
/**
* This method returns an URI based on OpenAIRE 3.0 guidelines
* This method returns an URI based on Openaire 3.0 guidelines
* https://guidelines.openaire.eu/en/latest/literature/field_projectid.html that
* can be used as an ID if is there any missing part, that part it will be
* replaced by the character '+'
@@ -281,7 +281,7 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider {
}
/**
* OpenAIRE Funding External Data Builder Class
* Openaire Funding External Data Builder Class
*
* @author pgraca
*/

View File

@@ -16,7 +16,7 @@ import org.dspace.qaevent.service.QAEventService;
import org.dspace.utils.DSpace;
/**
* Consumer to delete qaevents once the target item is deleted
* Consumer to delete qaevents from solr due to the target item deletion
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*

View File

@@ -11,7 +11,7 @@ import java.util.Date;
import java.util.UUID;
/**
* This model class represent the source/provider of the QA events (as OpenAIRE).
* This model class represent the source/provider of the QA events (as Openaire).
*
* @author Luca Giamminonni (luca.giamminonni at 4Science)
*

View File

@@ -22,7 +22,7 @@ import org.dspace.eperson.EPerson;
* @author Andrea Bollini (andrea.bollini at 4science.it)
*
*/
public interface QAEventsDao extends GenericDAO<QAEventProcessed> {
public interface QAEventsDAO extends GenericDAO<QAEventProcessed> {
/**
* Returns all the stored QAEventProcessed entities.

View File

@@ -17,16 +17,16 @@ import org.dspace.content.QAEventProcessed;
import org.dspace.core.AbstractHibernateDAO;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.qaevent.dao.QAEventsDao;
import org.dspace.qaevent.dao.QAEventsDAO;
/**
* Implementation of {@link QAEventsDao} that store processed events using an
* Implementation of {@link QAEventsDAO} that store processed events using an
* SQL DBMS.
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*
*/
public class QAEventsDaoImpl extends AbstractHibernateDAO<QAEventProcessed> implements QAEventsDao {
public class QAEventsDAOImpl extends AbstractHibernateDAO<QAEventProcessed> implements QAEventsDAO {
@Override
public List<QAEventProcessed> findAll(Context context) throws SQLException {
@@ -60,7 +60,7 @@ public class QAEventsDaoImpl extends AbstractHibernateDAO<QAEventProcessed> impl
public List<QAEventProcessed> searchByEventId(Context context, String eventId, Integer start, Integer size)
throws SQLException {
Query query = createQuery(context,
"SELECT * " + "FROM QAEventProcessed qaevent WHERE qaevent.qaevent_id = :event_id ");
"SELECT * FROM QAEventProcessed qaevent WHERE qaevent.qaevent_id = :event_id ");
query.setFirstResult(start);
query.setMaxResults(size);
query.setParameter("event_id", eventId);

View File

@@ -32,7 +32,7 @@ import org.dspace.content.QAEvent;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.factory.EPersonServiceFactory;
import org.dspace.qaevent.service.BrokerClientFactory;
import org.dspace.qaevent.service.OpenaireClientFactory;
import org.dspace.qaevent.service.QAEventService;
import org.dspace.scripts.DSpaceRunnable;
import org.dspace.services.ConfigurationService;
@@ -42,7 +42,9 @@ import org.dspace.utils.DSpace;
/**
* Implementation of {@link DSpaceRunnable} to perfom a QAEvents import from a
* json file. The JSON file contains an array of JSON Events, where each event
* has the following structure
* has the following structure. The message attribute follows the structure
* documented at
* @see <a href="https://graph.openaire.eu/docs/category/entities" target="_blank"> see </a>
*
* <code> <br/>
* { <br/>
@@ -103,7 +105,7 @@ public class OpenaireEventsImport
qaEventService = new DSpace().getSingletonService(QAEventService.class);
configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
brokerClient = BrokerClientFactory.getInstance().getBrokerClient();
brokerClient = OpenaireClientFactory.getInstance().getBrokerClient();
topicsToImport = configurationService.getArrayProperty("qaevents.openaire.import.topic");
openaireBrokerURL = getOpenaireBrokerUri();

View File

@@ -54,12 +54,12 @@ public class OpenaireEventsImportScriptConfiguration<T extends OpenaireEventsImp
if (options == null) {
Options options = new Options();
options.addOption("f", "file", true, "Import data from OpenAIRE quality assurance broker JSON file."
options.addOption("f", "file", true, "Import data from Openaire quality assurance broker JSON file."
+ " This parameter is mutually exclusive to the email parameter.");
options.getOption("f").setType(InputStream.class);
options.getOption("f").setRequired(false);
options.addOption("e", "email", true, "Email related to the subscriptions to import data from OpenAIRE "
options.addOption("e", "email", true, "Email related to the subscriptions to import data from Openaire "
+ "broker. This parameter is mutually exclusive to the file parameter.");
options.getOption("e").setType(String.class);
options.getOption("e").setRequired(false);

View File

@@ -16,7 +16,7 @@ import org.dspace.utils.DSpace;
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
*
*/
public interface BrokerClientFactory {
public interface OpenaireClientFactory {
/**
* Returns an instance of the {@link BrokerClient}.
@@ -25,7 +25,7 @@ public interface BrokerClientFactory {
*/
public BrokerClient getBrokerClient();
public static BrokerClientFactory getInstance() {
return new DSpace().getServiceManager().getServiceByName("brokerClientFactory", BrokerClientFactory.class);
public static OpenaireClientFactory getInstance() {
return new DSpace().getServiceManager().getServiceByName("openaireClientFactory", OpenaireClientFactory.class);
}
}

View File

@@ -24,6 +24,14 @@ import org.dspace.qaevent.QATopic;
*/
public interface QAEventService {
/**
* Find all the event's topics.
*
* @param offset the offset to apply
* @return the topics list
*/
public List<QATopic> findAllTopics(Context context, long offset, long count, String orderField, boolean ascending);
/**
* Find all the event's topics related to the given source.
*
@@ -33,7 +41,8 @@ public interface QAEventService {
* @param count the page size
* @return the topics list
*/
public List<QATopic> findAllTopicsBySource(Context context, String source, long offset, int count);
public List<QATopic> findAllTopicsBySource(Context context, String source, long offset, long count,
String orderField, boolean ascending);
/**
* Find a specific topic by its name, source and optionally a target.
@@ -186,11 +195,13 @@ public interface QAEventService {
* @param source (not null) the source to search for
* @param target the item referring to
* @param offset the offset to apply
* @param pageSize the page size
* @param count result count
* @param orderField field name for sorting
* @param ascending activate ascending sort
* @return the topics list
*/
public List<QATopic> findAllTopicsBySourceAndTarget(Context context, String source, UUID target, long offset,
int pageSize);
long count, String orderField, boolean ascending);
/**
* Count all the event's topics related to the given source referring to a specific item

View File

@@ -12,7 +12,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Implementation of {@link QAMessageDTO} that model message coming from OPENAIRE.
*
* @see <a href="https://graph.openaire.eu/docs/category/entities" target="_blank"> see </a>
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
*
*/

View File

@@ -8,17 +8,17 @@
package org.dspace.qaevent.service.impl;
import eu.dnetlib.broker.BrokerClient;
import org.dspace.qaevent.service.BrokerClientFactory;
import org.dspace.qaevent.service.OpenaireClientFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Implementation of {@link BrokerClientFactory} that returns the instance of
* Implementation of {@link OpenaireClientFactory} that returns the instance of
* {@link BrokerClient} managed by the Spring context.
*
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
*
*/
public class BrokerClientFactoryImpl implements BrokerClientFactory {
public class OpenaireClientFactoryImpl implements OpenaireClientFactory {
@Autowired
private BrokerClient brokerClient;

View File

@@ -40,6 +40,7 @@ import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.FacetParams;
import org.dspace.content.Item;
import org.dspace.content.QAEvent;
import org.dspace.content.service.ItemService;
@@ -50,8 +51,8 @@ import org.dspace.qaevent.AutomaticProcessingAction;
import org.dspace.qaevent.QAEventAutomaticProcessingEvaluation;
import org.dspace.qaevent.QASource;
import org.dspace.qaevent.QATopic;
import org.dspace.qaevent.dao.QAEventsDao;
import org.dspace.qaevent.dao.impl.QAEventsDaoImpl;
import org.dspace.qaevent.dao.QAEventsDAO;
import org.dspace.qaevent.dao.impl.QAEventsDAOImpl;
import org.dspace.qaevent.service.QAEventActionService;
import org.dspace.qaevent.service.QAEventSecurityService;
import org.dspace.qaevent.service.QAEventService;
@@ -60,11 +61,12 @@ import org.dspace.services.factory.DSpaceServicesFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
/**
* Implementation of {@link QAEventService} that use Solr to store events. When
* the user performs an action on the event (such as accepting the suggestion or
* rejecting it) then the event is removed from solr and saved in the database
* (see {@link QAEventsDao}) so that it is no longer proposed.
* (see {@link QAEventsDAO}) so that it is no longer proposed.
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*
@@ -86,7 +88,7 @@ public class QAEventServiceImpl implements QAEventService {
private HandleService handleService;
@Autowired
private QAEventsDaoImpl qaEventsDao;
private QAEventsDAOImpl qaEventsDao;
@Autowired(required = false)
@Qualifier("qaAutomaticProcessingMap")
@@ -240,19 +242,29 @@ public class QAEventServiceImpl implements QAEventService {
}
@Override
public List<QATopic> findAllTopicsBySource(Context context, String source, long offset, int count) {
return findAllTopicsBySourceAndTarget(context, source, null, offset, count);
public List<QATopic> findAllTopics(Context context, long offset, long count, String orderField, boolean ascending) {
return findAllTopicsBySource(context, null, offset, count, orderField, ascending);
}
@Override
public List<QATopic> findAllTopicsBySource(Context context, String source, long offset,
long count, String orderField, boolean ascending) {
return findAllTopicsBySourceAndTarget(context, source, null, offset, count, orderField, ascending);
}
@Override
public List<QATopic> findAllTopicsBySourceAndTarget(Context context, String source, UUID target, long offset,
int count) {
long count, String orderField, boolean ascending) {
if (isNotSupportedSource(source)
|| !qaSecurityService.canSeeSource(context, context.getCurrentUser(), source)) {
return List.of();
}
SolrQuery solrQuery = new SolrQuery();
solrQuery.setRows(0);
if (orderField != null) {
solrQuery.setSort(orderField, ascending ? ORDER.asc : ORDER.desc);
solrQuery.setFacetSort(FacetParams.FACET_SORT_INDEX);
}
Optional<String> securityQuery = qaSecurityService.generateQAEventFilterQuery(context,
context.getCurrentUser(), source);
solrQuery.setQuery(securityQuery.orElse("*:*"));