dnet-docker/dnet-app/apps/dnet-oai-manager/src/main/java/eu/dnetlib/services/oai/service/OaiService.java

152 lines
5.7 KiB
Java

package eu.dnetlib.services.oai.service;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import eu.dnetlib.common.mapping.xslt.XsltUtils;
import eu.dnetlib.domain.oai.ExportedOaiMetadataFormat;
import eu.dnetlib.domain.oai.ExportedOaiRecord;
import eu.dnetlib.domain.oai.ExportedOaiSet;
import eu.dnetlib.domain.oai.OaiConfiguration;
import eu.dnetlib.errors.DnetRuntimeException;
import eu.dnetlib.services.oai.domain.OaiPage;
import eu.dnetlib.services.oai.repository.ExportedOaiMetadataFormatRepository;
import eu.dnetlib.services.oai.repository.OaiConfigurationRepository;
import eu.dnetlib.services.oai.repository.OaiRecordRepository;
import eu.dnetlib.services.oai.repository.OaiSetRepository;
import eu.dnetlib.services.oai.utils.OaiPageRequest;
import eu.dnetlib.utils.DateUtils;
@Service
public class OaiService {
@Autowired
private OaiConfigurationRepository oaiConfigurationRepository;
@Autowired
private OaiSetRepository oaiSetRepository;
@Autowired
private ExportedOaiMetadataFormatRepository oaiMetadataFormatRepository;
@Autowired
private OaiRecordRepository oaiRecordRepository;
private static final int CONFIGURATION_ID = 0;
private static final int OAI_PAGE_SIZE = 100;
@Cacheable(value = "oaiConfiguration", key = "#root.methodName")
public OaiConfiguration oaiConfiguration() {
return this.oaiConfigurationRepository.findById(CONFIGURATION_ID).orElseThrow(() -> new DnetRuntimeException("Missing OAI Configuration"));
}
@CacheEvict(value = "oaiConfiguration", allEntries = true)
public OaiConfiguration oaiConfiguration(final OaiConfiguration conf) {
conf.setId(CONFIGURATION_ID);
return this.oaiConfigurationRepository.save(conf);
}
@Cacheable(value = "oaiSets", key = "#root.methodName")
public List<ExportedOaiSet> listSets() {
return this.oaiSetRepository.findAll();
}
@CacheEvict(value = "oaiSets", allEntries = true)
public void addOrUpdateSet(final ExportedOaiSet set) {
this.oaiSetRepository.save(set);
}
@CacheEvict(value = "oaiSets", allEntries = true)
public void deleteSet(final String setSpec) {
this.oaiRecordRepository.deleteByOaiSet(setSpec);
this.oaiSetRepository.deleteById(setSpec);
}
public List<ExportedOaiMetadataFormat> listMetadataFormats(final String id) {
return this.oaiRecordRepository.existsById(id) ? this.oaiMetadataFormatRepository.findAll() : new ArrayList<>();
}
@Cacheable(value = "oaiMetadataFormats", key = "#root.methodName")
public List<ExportedOaiMetadataFormat> listMetadataFormats() {
return this.oaiMetadataFormatRepository.findAll();
}
@CacheEvict(value = "oaiMetadataFormats", allEntries = true)
public void addOrUpdateMetadataFormat(final ExportedOaiMetadataFormat format) {
// TODO (LOW PRIORITY) : probably other controls are necessary
this.oaiMetadataFormatRepository.save(format);
}
@CacheEvict(value = "oaiMetadataFormats", allEntries = true)
public void deleteMetadataFormat(final String metadataPrefix) {
// TODO (LOW PRIORITY) : probably other controls are necessary
this.oaiMetadataFormatRepository.deleteById(metadataPrefix);
}
public boolean verifySet(final String setSpec) {
// a blank setSpec is correct (it is equivalent to all sets)
return StringUtils.isBlank(setSpec) || this.oaiSetRepository.existsById(setSpec);
}
public ExportedOaiRecord getRecord(final String id, final String metadataPrefix) {
final ExportedOaiRecord record = this.oaiRecordRepository.findById(id).orElseThrow(() -> new DnetRuntimeException("Missing ID: " + id));
if (!metadataPrefix.equalsIgnoreCase(oaiConfiguration().getNativeFormat())) {
final String xslt = listMetadataFormats()
.stream()
.filter(f -> f.getMetadataPrefix().equalsIgnoreCase(metadataPrefix))
.map(ExportedOaiMetadataFormat::getXslt)
.findFirst()
.orElseThrow(() -> new DnetRuntimeException("Invalid metadata format: " + metadataPrefix));
try {
record.setBody(XsltUtils.applyXslt(record.getBody(), xslt));
} catch (final Exception e) {
throw new DnetRuntimeException("Error processing record", e);
}
}
return record;
}
public OaiPage listRecords(final String metadataPrefix, final String set, final String from, final String until) {
final LocalDate fromDate = StringUtils.isNotBlank(from) ? DateUtils.parseDate(from) : LocalDate.MIN;
final LocalDate untilDate = StringUtils.isNotBlank(until) ? DateUtils.parseDate(until).plusDays(1) : LocalDate.MAX;
return listRecords(OaiPageRequest.prepareRequest(metadataPrefix, set, fromDate, untilDate, 0, OAI_PAGE_SIZE));
}
public OaiPage listRecords(final String resumptionToken) {
return listRecords(OaiPageRequest.fromResumptionToken(resumptionToken));
}
private OaiPage listRecords(final OaiPageRequest req) {
final PageRequest pageRequest = PageRequest.of(req.getPageNumber(), req.getPageSize(), Sort.by("id"));
final LocalDate from = req.getFrom();
final LocalDate until = req.getUntil();
final Page<ExportedOaiRecord> page =
StringUtils.isBlank(req.getSet()) ? this.oaiRecordRepository.findByOaiSetAndDateBetween(req.getSet(), from, until, pageRequest)
: this.oaiRecordRepository.findByDateBetween(from, until, pageRequest);
final OaiPage res = new OaiPage();
res.setCursor(req.getPageSize() * req.getPageNumber());
res.setTotal(page.getTotalElements());
res.setList(page.getContent());
res.setResumptionToken(req.nextResumptionToken());
return res;
}
}