Merge pull request #8236 from 4Science/CST-5303-LiveImport-3PR

Migrate extra DSpace-CRIS "Live Import" sources to DSpace (SciELO)
This commit is contained in:
Tim Donohue
2022-05-25 13:43:06 -05:00
committed by GitHub
12 changed files with 874 additions and 1 deletions

View File

@@ -0,0 +1,59 @@
/**
* 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.importer.external.metadatamapping.contributor;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.dspace.importer.external.metadatamapping.MetadataFieldConfig;
import org.dspace.importer.external.metadatamapping.MetadatumDTO;
/**
* This contributor extends SimpleRisToMetadataContributor,
* in particular, this one is able to chain multi values into a single one
*
* @author Mykhaylo Boychuk (mykhaylo.boychuk at 4science.it)
*/
public class SimpleRisToMetadataConcatContributor extends SimpleRisToMetadataContributor {
private String tag;
private MetadataFieldConfig metadata;
@Override
public Collection<MetadatumDTO> contributeMetadata(Map<String, List<String>> record) {
List<MetadatumDTO> values = new LinkedList<>();
List<String> fieldValues = record.get(this.tag);
Optional.ofNullable(fieldValues)
.map(fv -> fv.stream())
.map(s -> s.collect(Collectors.joining(" ")))
.ifPresent(t -> values.add(this.metadataFieldMapping.toDCValue(this.metadata, t)));
return values;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public MetadataFieldConfig getMetadata() {
return metadata;
}
public void setMetadata(MetadataFieldConfig metadata) {
this.metadata = metadata;
}
}

View File

@@ -0,0 +1,71 @@
/**
* 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.importer.external.metadatamapping.contributor;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.dspace.importer.external.metadatamapping.MetadataFieldConfig;
import org.dspace.importer.external.metadatamapping.MetadataFieldMapping;
import org.dspace.importer.external.metadatamapping.MetadatumDTO;
/**
* Metadata contributor that takes a record defined as Map<String,List<String>>
* and turns it into metadatums configured in fieldToMetadata
*
* @author Mykhaylo Boychuk (mykhaylo.boychuk at 4science.it)
*/
public class SimpleRisToMetadataContributor implements MetadataContributor<Map<String,List<String>>> {
protected Map<String, MetadataFieldConfig> fieldToMetadata;
protected MetadataFieldMapping<Map<String,List<String>>,
MetadataContributor<Map<String,List<String>>>> metadataFieldMapping;
public SimpleRisToMetadataContributor() {}
public SimpleRisToMetadataContributor(Map<String, MetadataFieldConfig> fieldToMetadata) {
this.fieldToMetadata = fieldToMetadata;
}
@Override
public Collection<MetadatumDTO> contributeMetadata(Map<String, List<String>> record) {
List<MetadatumDTO> values = new LinkedList<>();
for (String field : fieldToMetadata.keySet()) {
List<String> fieldValues = record.get(field);
if (Objects.nonNull(fieldValues)) {
for (String value : fieldValues) {
values.add(metadataFieldMapping.toDCValue(fieldToMetadata.get(field), value));
}
}
}
return values;
}
public Map<String, MetadataFieldConfig> getFieldToMetadata() {
return fieldToMetadata;
}
public void setFieldToMetadata(Map<String, MetadataFieldConfig> fieldToMetadata) {
this.fieldToMetadata = fieldToMetadata;
}
public MetadataFieldMapping<Map<String, List<String>>,
MetadataContributor<Map<String, List<String>>>> getMetadataFieldMapping() {
return metadataFieldMapping;
}
public void setMetadataFieldMapping(MetadataFieldMapping<Map<String, List<String>>,
MetadataContributor<Map<String, List<String>>>> metadataFieldMapping) {
this.metadataFieldMapping = metadataFieldMapping;
}
}

View File

@@ -0,0 +1,37 @@
/**
* 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.importer.external.scielo.service;
import java.util.Map;
import javax.annotation.Resource;
import org.dspace.importer.external.metadatamapping.AbstractMetadataFieldMapping;
/**
* An implementation of {@link AbstractMetadataFieldMapping}
* Responsible for defining the mapping of the Scielo metadatum fields on the DSpace metadatum fields
*
* @author Boychuk Mykhaylo (boychuk.mykhaylo at 4science dot it)
*/
@SuppressWarnings("rawtypes")
public class ScieloFieldMapping extends AbstractMetadataFieldMapping {
/**
* Defines which metadatum is mapped on which metadatum. Note that while the key must be unique it
* only matters here for postprocessing of the value. The mapped MetadatumContributor has full control over
* what metadatafield is generated.
*
* @param metadataFieldMap The map containing the link between retrieve metadata and
* metadata that will be set to the item.
*/
@Override
@SuppressWarnings("unchecked")
@Resource(name = "scieloMetadataFieldMap")
public void setMetadataFieldMap(Map metadataFieldMap) {
super.setMetadataFieldMap(metadataFieldMap);
}
}

View File

@@ -0,0 +1,263 @@
/**
* 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.importer.external.scielo.service;
import java.io.BufferedReader;
import java.io.StringReader;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.el.MethodNotFoundException;
import javax.ws.rs.BadRequestException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.http.client.utils.URIBuilder;
import org.dspace.content.Item;
import org.dspace.importer.external.datamodel.ImportRecord;
import org.dspace.importer.external.datamodel.Query;
import org.dspace.importer.external.exception.FileSourceException;
import org.dspace.importer.external.exception.MetadataSourceException;
import org.dspace.importer.external.liveimportclient.service.LiveImportClient;
import org.dspace.importer.external.service.AbstractImportMetadataSourceService;
import org.dspace.importer.external.service.components.QuerySource;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Implements a data source for querying Scielo
*
* @author Boychuk Mykhaylo (boychuk.mykhaylo at 4Science dot it)
*/
public class ScieloImportMetadataSourceServiceImpl extends AbstractImportMetadataSourceService<Map<String,List<String>>>
implements QuerySource {
/**
* This pattern is used when reading the Scielo response,
* to check if the fields you are reading is in rid format
*/
private static final String PATTERN = "^([A-Z][A-Z0-9]) - (.*)$";
/**
* This pattern is used to verify correct format of ScieloId
*/
private static final String ID_PATTERN = "^(.....)-(.*)-(...)$";
private int timeout = 1000;
private String url;
@Autowired
private LiveImportClient liveImportClient;
@Override
public void init() throws Exception {}
@Override
public String getImportSource() {
return "scielo";
}
@Override
public Collection<ImportRecord> getRecords(String query, int start, int count) throws MetadataSourceException {
return retry(new SearchByQueryCallable(query, count, start));
}
@Override
public Collection<ImportRecord> getRecords(Query query) throws MetadataSourceException {
return retry(new SearchByQueryCallable(query));
}
@Override
public ImportRecord getRecord(Query query) throws MetadataSourceException {
List<ImportRecord> records = retry(new SearchByQueryCallable(query));
return CollectionUtils.isEmpty(records) ? null : records.get(0);
}
@Override
public ImportRecord getRecord(String id) throws MetadataSourceException {
List<ImportRecord> records = retry(new FindByIdCallable(id));
return CollectionUtils.isEmpty(records) ? null : records.get(0);
}
@Override
public int getRecordsCount(String query) throws MetadataSourceException {
return retry(new SearchNBByQueryCallable(query));
}
@Override
public int getRecordsCount(Query query) throws MetadataSourceException {
throw new MethodNotFoundException("This method is not implemented for Scielo");
}
@Override
public Collection<ImportRecord> findMatchingRecords(Item item) throws MetadataSourceException {
throw new MethodNotFoundException("This method is not implemented for Scielo");
}
@Override
public Collection<ImportRecord> findMatchingRecords(Query query) throws MetadataSourceException {
throw new MethodNotFoundException("This method is not implemented for Scielo");
}
/**
* This class is a Callable implementation to count the number of entries for an Scielo query
*
* @author Mykhaylo Boychuk (mykhaylo.boychuk@4science.com)
*/
private class SearchNBByQueryCallable implements Callable<Integer> {
private String query;
private SearchNBByQueryCallable(String queryString) {
this.query = queryString;
}
private SearchNBByQueryCallable(Query query) {
this.query = query.getParameterAsClass("query", String.class);
}
@Override
public Integer call() throws Exception {
URIBuilder uriBuilder = new URIBuilder(url + URLEncoder.encode(query, StandardCharsets.UTF_8));
String resp = liveImportClient.executeHttpGetRequest(timeout, uriBuilder.toString(),
new HashMap<String, String>());
Map<Integer, Map<String, List<String>>> records = getRecords(resp);
return Objects.nonNull(records.size()) ? records.size() : 0;
}
}
/**
* This class is a Callable implementation to get an Scielo entry using ScieloID
* The ScieloID to use can be passed through the constructor as a String
* or as Query's map entry, with the key "id".
*
* @author Mykhaylo Boychuk (mykhaylo.boychuk@4science.com)
*/
private class FindByIdCallable implements Callable<List<ImportRecord>> {
private String id;
private FindByIdCallable(String id) {
this.id = id;
}
@Override
public List<ImportRecord> call() throws Exception {
List<ImportRecord> results = new ArrayList<>();
String scieloId = id.trim();
Pattern risPattern = Pattern.compile(ID_PATTERN);
Matcher risMatcher = risPattern.matcher(scieloId);
if (risMatcher.matches()) {
URIBuilder uriBuilder = new URIBuilder(url + URLEncoder.encode(scieloId, StandardCharsets.UTF_8));
String resp = liveImportClient.executeHttpGetRequest(timeout, uriBuilder.toString(),
new HashMap<String, String>());
Map<Integer, Map<String, List<String>>> records = getRecords(resp);
if (Objects.nonNull(records) & !records.isEmpty()) {
results.add(transformSourceRecords(records.get(1)));
}
} else {
throw new BadRequestException("id provided : " + scieloId + " is not an ScieloID");
}
return results;
}
}
/**
* This class is a Callable implementation to get Scielo entries based on query object.
* This Callable use as query value the string queryString passed to constructor.
* If the object will be construct through Query.class instance, a Query's map entry with key "query" will be used.
* Pagination is supported too, using the value of the Query's map with keys "start" and "count".
*
* @author Mykhaylo Boychuk (mykhaylo.boychuk@4science.com)
*/
private class SearchByQueryCallable implements Callable<List<ImportRecord>> {
private Query query;
private SearchByQueryCallable(String queryString, Integer maxResult, Integer start) {
query = new Query();
query.addParameter("query", queryString);
query.addParameter("start", start);
query.addParameter("count", maxResult);
}
private SearchByQueryCallable(Query query) {
this.query = query;
}
@Override
public List<ImportRecord> call() throws Exception {
List<ImportRecord> results = new ArrayList<>();
String q = query.getParameterAsClass("query", String.class);
Integer count = query.getParameterAsClass("count", Integer.class);
Integer start = query.getParameterAsClass("start", Integer.class);
URIBuilder uriBuilder = new URIBuilder(url + URLEncoder.encode(q, StandardCharsets.UTF_8));
uriBuilder.addParameter("start", start.toString());
uriBuilder.addParameter("count", count.toString());
String resp = liveImportClient.executeHttpGetRequest(timeout, uriBuilder.toString(),
new HashMap<String, String>());
Map<Integer, Map<String, List<String>>> records = getRecords(resp);
for (int record : records.keySet()) {
results.add(transformSourceRecords(records.get(record)));
}
return results;
}
}
private Map<Integer, Map<String,List<String>>> getRecords(String resp) throws FileSourceException {
Map<Integer, Map<String, List<String>>> records = new HashMap<Integer, Map<String,List<String>>>();
BufferedReader reader;
int countRecord = 0;
try {
reader = new BufferedReader(new StringReader(resp));
String line;
while ((line = reader.readLine()) != null) {
if (line.isEmpty() || line.equals("") || line.matches("^\\s*$")) {
continue;
}
line = line.replaceAll("\\uFEFF", "").trim();
Pattern risPattern = Pattern.compile(PATTERN);
Matcher risMatcher = risPattern.matcher(line);
if (risMatcher.matches()) {
if (risMatcher.group(1).equals("TY") & risMatcher.group(2).equals("JOUR")) {
countRecord ++;
Map<String,List<String>> newMap = new HashMap<String, List<String>>();
records.put(countRecord, newMap);
} else {
Map<String, List<String>> tag2values = records.get(countRecord);
List<String> values = tag2values.get(risMatcher.group(1));
if (Objects.isNull(values)) {
List<String> newValues = new ArrayList<String>();
newValues.add(risMatcher.group(2));
tag2values.put(risMatcher.group(1), newValues);
} else {
values.add(risMatcher.group(2));
tag2values.put(risMatcher.group(1), values);
}
}
}
}
} catch (Exception e) {
throw new FileSourceException("Cannot parse RIS file", e);
}
return records;
}
public void setUrl(String url) {
this.url = url;
}
}

View File

@@ -13,7 +13,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Utility class that provides methods to check if a given string is a DOI and exists on CrossRef services
* Utility class that provides methods to check if a given string is a DOI
*
* @author Corrado Lombardi (corrado.lombardi at 4science.it)
*/

View File

@@ -130,6 +130,12 @@
</bean>
<bean id="vufindMetadataFieldMapping" class="org.dspace.importer.external.vufind.metadatamapping.VuFindFieldMapping"/>
<bean id="ScieloImportService" class="org.dspace.importer.external.scielo.service.ScieloImportMetadataSourceServiceImpl" scope="singleton">
<property name="metadataFieldMapping" ref="scieloMetadataFieldMapping"/>
<property name="url" value="${scielo.url}"/>
</bean>
<bean id="scieloMetadataFieldMapping" class="org.dspace.importer.external.scielo.service.ScieloFieldMapping"/>
<!-- Metadatafield used to check against if it's already imported or not during the JSONLookupSearcher-->
<bean id="lookupID" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<constructor-arg value="dc.identifier.other"/>

View File

@@ -0,0 +1,236 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.when;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import javax.el.MethodNotFoundException;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.impl.client.CloseableHttpClient;
import org.dspace.builder.CollectionBuilder;
import org.dspace.builder.CommunityBuilder;
import org.dspace.builder.ItemBuilder;
import org.dspace.content.Item;
import org.dspace.importer.external.datamodel.ImportRecord;
import org.dspace.importer.external.datamodel.Query;
import org.dspace.importer.external.liveimportclient.service.LiveImportClientImpl;
import org.dspace.importer.external.metadatamapping.MetadatumDTO;
import org.dspace.importer.external.scielo.service.ScieloImportMetadataSourceServiceImpl;
import org.junit.Test;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Integration tests for {@link ScieloImportMetadataSourceServiceImpl}
*
* @author Mykhaylo Boychuk (mykhaylo.boychuk at 4science.com)
*/
public class ScieloImportMetadataSourceServiceIT extends AbstractLiveImportIntegrationTest {
@Autowired
private LiveImportClientImpl liveImportClientImpl;
@Autowired
private ScieloImportMetadataSourceServiceImpl scieloServiceImpl;
@Test
public void scieloImportMetadataGetRecordsTest() throws Exception {
context.turnOffAuthorisationSystem();
CloseableHttpClient originalHttpClient = liveImportClientImpl.getHttpClient();
CloseableHttpClient httpClient = Mockito.mock(CloseableHttpClient.class);
try (InputStream scieloResp = getClass().getResourceAsStream("scielo-test.txt")) {
String scieloRipResp = IOUtils.toString(scieloResp, Charset.defaultCharset());
liveImportClientImpl.setHttpClient(httpClient);
CloseableHttpResponse response = mockResponse(scieloRipResp, 200, "OK");
when(httpClient.execute(ArgumentMatchers.any())).thenReturn(response);
context.restoreAuthSystemState();
ArrayList<ImportRecord> collection2match = getRecords();
Collection<ImportRecord> recordsImported = scieloServiceImpl.getRecords("test query", 0, 2);
assertEquals(2, recordsImported.size());
matchRecords(new ArrayList<ImportRecord>(recordsImported), collection2match);
} finally {
liveImportClientImpl.setHttpClient(originalHttpClient);
}
}
@Test
public void scieloImportMetadataGetRecordsCountTest() throws Exception {
context.turnOffAuthorisationSystem();
CloseableHttpClient originalHttpClient = liveImportClientImpl.getHttpClient();
CloseableHttpClient httpClient = Mockito.mock(CloseableHttpClient.class);
try (InputStream file = getClass().getResourceAsStream("scielo-test.txt")) {
String scieloResp = IOUtils.toString(file, Charset.defaultCharset());
liveImportClientImpl.setHttpClient(httpClient);
CloseableHttpResponse response = mockResponse(scieloResp, 200, "OK");
when(httpClient.execute(ArgumentMatchers.any())).thenReturn(response);
context.restoreAuthSystemState();
int tot = scieloServiceImpl.getRecordsCount("test query");
assertEquals(2, tot);
} finally {
liveImportClientImpl.setHttpClient(originalHttpClient);
}
}
@Test(expected = MethodNotFoundException.class)
public void scieloImportMetadataFindMatchingRecordsTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
org.dspace.content.Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1")
.build();
Item testItem = ItemBuilder.createItem(context, col1)
.withTitle("test item")
.withIssueDate("2021")
.build();
context.restoreAuthSystemState();
scieloServiceImpl.findMatchingRecords(testItem);
}
@Test(expected = MethodNotFoundException.class)
public void scieloImportMetadataGetRecordsCountByQueryTest() throws Exception {
Query q = new Query();
q.addParameter("query", "test query");
scieloServiceImpl.getRecordsCount(q);
}
@Test
public void scieloImportMetadataGetRecordsByIdTest() throws Exception {
context.turnOffAuthorisationSystem();
CloseableHttpClient originalHttpClient = liveImportClientImpl.getHttpClient();
CloseableHttpClient httpClient = Mockito.mock(CloseableHttpClient.class);
try (InputStream scieloResp = getClass().getResourceAsStream("scielo-single-record.txt")) {
String scieloRipResp = IOUtils.toString(scieloResp, Charset.defaultCharset());
liveImportClientImpl.setHttpClient(httpClient);
CloseableHttpResponse response = mockResponse(scieloRipResp, 200, "OK");
when(httpClient.execute(ArgumentMatchers.any())).thenReturn(response);
context.restoreAuthSystemState();
ArrayList<ImportRecord> collection2match = getRecords();
collection2match.remove(1);
ImportRecord record = scieloServiceImpl.getRecord("S0185-30582021000200231-mex");
assertNotNull(record);
Collection<ImportRecord> recordsImported = Arrays.asList(record);
matchRecords(new ArrayList<ImportRecord>(recordsImported), collection2match);
} finally {
liveImportClientImpl.setHttpClient(originalHttpClient);
}
}
private ArrayList<ImportRecord> getRecords() {
ArrayList<ImportRecord> records = new ArrayList<>();
//define first record
List<MetadatumDTO> metadatums = new ArrayList<MetadatumDTO>();
MetadatumDTO ispartof = createMetadatumDTO("dc", "relation", "ispartof", "Nova tellus");
MetadatumDTO date = createMetadatumDTO("dc", "date", "issued", "2021");
MetadatumDTO citation = createMetadatumDTO("oaire", "citation", "issue", "2");
MetadatumDTO doi = createMetadatumDTO("dc", "identifier", "doi", "10.19130/iifl.nt.2021.39.2.901");
MetadatumDTO endPage = createMetadatumDTO("oaire", "citation", "endPage", "236");
MetadatumDTO subject = createMetadatumDTO("dc", "subject", null, "Roma");
MetadatumDTO subject2 = createMetadatumDTO("dc", "subject", null, "Historia");
MetadatumDTO subject3 = createMetadatumDTO("dc", "subject", null, "ritos funerarios");
MetadatumDTO subject4 = createMetadatumDTO("dc", "subject", null, "inframundo");
MetadatumDTO subject5 = createMetadatumDTO("dc", "subject", null, "epitafios");
MetadatumDTO author = createMetadatumDTO("dc", "contributor", "author", "Torres Marzo, Ricardo");
MetadatumDTO title = createMetadatumDTO("dc", "title", null, "Requena Jiménez, Miguel, Los espacios"
+ " de la muerte en Roma, Madrid, Síntesis, 2021, 365 págs."
+ " más bibliografía en línea, ISBN 978-84-135759-6-4.");
MetadatumDTO volume = createMetadatumDTO("oaire", "citation", "volume", "39");
MetadatumDTO issn = createMetadatumDTO("dc", "identifier", "issn", "0185-3058");
MetadatumDTO other = createMetadatumDTO("dc", "identifier", "other", "S0185-30582021000200231-mex");
MetadatumDTO startPage = createMetadatumDTO("oaire", "citation", "startPage", "231");
metadatums.add(ispartof);
metadatums.add(date);
metadatums.add(citation);
metadatums.add(doi);
metadatums.add(endPage);
metadatums.add(subject);
metadatums.add(subject2);
metadatums.add(subject3);
metadatums.add(subject4);
metadatums.add(subject5);
metadatums.add(author);
metadatums.add(title);
metadatums.add(volume);
metadatums.add(issn);
metadatums.add(other);
metadatums.add(startPage);
ImportRecord firstrRecord = new ImportRecord(metadatums);
//define second record
List<MetadatumDTO> metadatums2 = new ArrayList<MetadatumDTO>();
MetadatumDTO ispartof2 = createMetadatumDTO("dc", "relation", "ispartof", "Revista de Derecho Privado");
MetadatumDTO date2 = createMetadatumDTO("dc", "date", "issued", "2021");
MetadatumDTO citation2 = createMetadatumDTO("oaire", "citation", "issue", "41");
MetadatumDTO doi2 = createMetadatumDTO("dc", "identifier", "doi", "10.18601/01234366.n41.14");
MetadatumDTO endPage2 = createMetadatumDTO("oaire", "citation", "endPage", "418");
MetadatumDTO subject6 = createMetadatumDTO("dc", "subject", null, "sopravvenienza contrattuale");
MetadatumDTO subject7 = createMetadatumDTO("dc", "subject", null, "covro");
MetadatumDTO subject8 = createMetadatumDTO("dc", "subject", null, "buona fede in senso oggettivo");
MetadatumDTO subject9 = createMetadatumDTO("dc", "subject", null, "obbligo di rinegoziare");
MetadatumDTO subject10 = createMetadatumDTO("dc", "subject", null, "revisione del contratto");
MetadatumDTO author2 = createMetadatumDTO("dc", "contributor", "author", "MAGRI, GEO");
MetadatumDTO title2 = createMetadatumDTO("dc", "title", null,
"Rinegoziazione e revisione del contratto. Tribunale di Roma, Sez. VI, 27 agosto 2020");
MetadatumDTO issn2 = createMetadatumDTO("dc", "identifier", "issn", "0123-4366");
MetadatumDTO other2 = createMetadatumDTO("dc", "identifier", "other", "S0123-43662021000200397-col");
MetadatumDTO startPage2 = createMetadatumDTO("oaire", "citation", "startPage", "397");
MetadatumDTO description = createMetadatumDTO("dc", "description", "abstract",
"ABSTRACT: The Tribunal of Rome imposes an obligation to renegotiate long-term contracts,"
+ " the balance of which has been modified by the covro pandemic. The decision establishes a"
+ " general obligation for the parties to execute the contract in good faith and gives the judge"
+ " the possibility of a judicial review. This is a long-awaited decision in doctrine which complies"
+ " with the indications of the Supreme Court of Cassation expressed in its memorandum 56/2020.");
metadatums2.add(ispartof2);
metadatums2.add(date2);
metadatums2.add(citation2);
metadatums2.add(doi2);
metadatums2.add(endPage2);
metadatums2.add(subject6);
metadatums2.add(subject7);
metadatums2.add(subject8);
metadatums2.add(subject9);
metadatums2.add(subject10);
metadatums2.add(author2);
metadatums2.add(title2);
metadatums2.add(issn2);
metadatums2.add(other2);
metadatums2.add(startPage2);
metadatums2.add(description);
ImportRecord secondRecord = new ImportRecord(metadatums2);
records.add(firstrRecord);
records.add(secondRecord);
return records;
}
}

View File

@@ -0,0 +1,24 @@
TY - JOUR
AU - Torres Marzo, Ricardo
TI - Requena Jiménez, Miguel, Los espacios de la muerte en Roma, Madrid, Síntesis, 2021, 365 págs. más bibliografía en línea, ISBN 978-84-135759-6-4.
JO - Nova tellus
J2 - Nova tellus
SN - 0185-3058
VL - 39
IS - 2
DO - 10.19130/iifl.nt.2021.39.2.901
DB - SciELO México
DP - http://www.scielo.org/
ID - S0185-30582021000200231-mex
LA - es
SP - 231
EP - 236
DA - 2021-12
PY - 2021
UR - http://www.scielo.org.mx/scielo.php?script=sci_arttext&pid=S0185-30582021000200231&lang=pt
KW - Roma
KW - Historia
KW - ritos funerarios
KW - inframundo
KW - epitafios
ER -

View File

@@ -0,0 +1,51 @@
TY - JOUR
AU - Torres Marzo, Ricardo
TI - Requena Jiménez, Miguel, Los espacios de la muerte en Roma, Madrid, Síntesis, 2021, 365 págs. más bibliografía en línea, ISBN 978-84-135759-6-4.
JO - Nova tellus
J2 - Nova tellus
SN - 0185-3058
VL - 39
IS - 2
DO - 10.19130/iifl.nt.2021.39.2.901
DB - SciELO México
DP - http://www.scielo.org/
ID - S0185-30582021000200231-mex
LA - es
SP - 231
EP - 236
DA - 2021-12
PY - 2021
UR - http://www.scielo.org.mx/scielo.php?script=sci_arttext&pid=S0185-30582021000200231&lang=pt
KW - Roma
KW - Historia
KW - ritos funerarios
KW - inframundo
KW - epitafios
ER -
TY - JOUR
AU - MAGRI, GEO
TI - Rinegoziazione e revisione del contratto. Tribunale di Roma, Sez. VI, 27 agosto 2020
JO - Revista de Derecho Privado
J2 - Rev. Derecho Privado
SN - 0123-4366
VL -
IS - 41
DO - 10.18601/01234366.n41.14
DB - SciELO Colômbia
DP - http://www.scielo.org/
ID - S0123-43662021000200397-col
LA - it
SP - 397
EP - 418
DA - 2021-12
PY - 2021
AB - ABSTRACT: The Tribunal of Rome imposes an obligation to renegotiate long-term contracts, the balance of which has been modified by the covro pandemic. The decision establishes a general obligation for the parties to execute the contract in good faith and gives the judge the possibility of a judicial review. This is a long-awaited decision in doctrine which complies with the indications of the Supreme Court of Cassation expressed in its memorandum 56/2020.
UR - http://www.scielo.org.co/scielo.php?script=sci_arttext&pid=S0123-43662021000200397&lang=pt
L1 - http://www.scielo.org.co/pdf/rdp/n41/0123-4366-rdp-41-397.pdf
KW - sopravvenienza contrattuale
KW - covro
KW - buona fede in senso oggettivo
KW - obbligo di rinegoziare
KW - revisione del contratto
ER -

View File

@@ -19,4 +19,10 @@ crossref.url = https://api.crossref.org/works
vufind.url = https://vufind.org/advanced_demo/api/v1/record
vufind.url.search = https://vufind.org/advanced_demo/api/v1/search
#################################################################
#---------------------- Scielo -----------------------------#
#---------------------------------------------------------------#
scielo.url = https://search.scielo.org/?output=ris&q=
#################################################################

View File

@@ -118,4 +118,15 @@
</property>
</bean>
<bean id="scieloLiveImportDataProvider" class="org.dspace.external.provider.impl.LiveImportDataProvider">
<property name="metadataSource" ref="ScieloImportService"/>
<property name="sourceIdentifier" value="scielo"/>
<property name="recordIdMetadata" value="dc.identifier.other"/>
<property name="supportedEntityTypes">
<list>
<value>Publication</value>
</list>
</property>
</bean>
</beans>

View File

@@ -0,0 +1,109 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd"
default-autowire-candidates="*Service,*DAO,javax.sql.DataSource">
<context:annotation-config/>
<!-- allows us to use spring annotations in beans -->
<util:map id="scieloMetadataFieldMap" key-type="org.dspace.importer.external.metadatamapping.MetadataFieldConfig"
value-type="org.dspace.importer.external.metadatamapping.contributor.MetadataContributor">
<description>Defines which metadatum is mapped on which metadatum. Note that while the key must be unique it
only matters here for postprocessing of the value. The mapped MetadatumContributor has full control over
what metadatafield is generated.
</description>
<entry key-ref="scielo.doi" value-ref="scieloSimpleContrib"/>
<entry key-ref="scielo.abstract" value-ref="scieloAbstractContrib"/>
</util:map>
<bean id="scieloAbstractContrib" class="org.dspace.importer.external.metadatamapping.contributor.SimpleRisToMetadataConcatContributor">
<property name="tag" value="AB"/>
<property name="metadata" ref="scielo.abstract"/>
</bean>
<bean id="scielo.abstract" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<constructor-arg value="dc.description.abstract"/>
</bean>
<bean id="scieloSimpleContrib" class="org.dspace.importer.external.metadatamapping.contributor.SimpleRisToMetadataContributor">
<property name="fieldToMetadata" ref="tag2metadata"/>
</bean>
<util:map id="tag2metadata" map-class="java.util.HashMap"
key-type="java.lang.String" value-type="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<entry key="DO" value-ref="scielo.doi"/>
<entry key="AU" value-ref="scielo.author"/>
<entry key="TI" value-ref="scielo.title"/>
<entry key="SN" value-ref="scielo.issn"/>
<entry key="VL" value-ref="scielo.volume"/>
<entry key="IS" value-ref="scielo.issueIdentifier"/>
<entry key="ID" value-ref="scielo.id"/>
<entry key="SP" value-ref="scielo.startPage"/>
<entry key="EP" value-ref="scielo.endPage"/>
<entry key="KW" value-ref="scielo.keywords"/>
<entry key="TY" value-ref="scielo.type"/>
<entry key="PY" value-ref="scielo.publicationYear"/>
<entry key="JO" value-ref="scielo.isPartOf"/>
</util:map>
<bean id="scielo.doi" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<constructor-arg value="dc.identifier.doi"/>
</bean>
<bean id="scielo.author" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<constructor-arg value="dc.contributor.author"/>
</bean>
<bean id="scielo.title" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<constructor-arg value="dc.title"/>
</bean>
<bean id="scielo.issn" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<constructor-arg value="dc.identifier.issn"/>
</bean>
<bean id="scielo.volume" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<constructor-arg value="oaire.citation.volume"/>
</bean>
<bean id="scielo.issueIdentifier" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<constructor-arg value="oaire.citation.issue"/>
</bean>
<bean id="scielo.id" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<constructor-arg value="dc.identifier.other"/>
</bean>
<bean id="scielo.startPage" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<constructor-arg value="oaire.citation.startPage"/>
</bean>
<bean id="scielo.endPage" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<constructor-arg value="oaire.citation.endPage"/>
</bean>
<bean id="scielo.keywords" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<constructor-arg value="dc.subject"/>
</bean>
<bean id="scielo.type" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<constructor-arg value="dc.type"/>
</bean>
<bean id="scielo.publicationYear" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<constructor-arg value="dc.date.issued"/>
</bean>
<bean id="scielo.isPartOf" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
<constructor-arg value="dc.relation.ispartof"/>
</bean>
</beans>