dnet-docker/dnet-app/libs/dnet-oai-common/src/main/java/eu/dnetlib/common/oai/OaiClient.java

173 lines
5.7 KiB
Java

package eu.dnetlib.common.oai;
import java.util.List;
import java.util.function.Function;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import eu.dnetlib.domain.oai.OaiIdentifier;
import eu.dnetlib.domain.oai.OaiInfo;
import eu.dnetlib.domain.oai.OaiMetadataFormat;
import eu.dnetlib.domain.oai.OaiRecord;
import eu.dnetlib.domain.oai.OaiSet;
public class OaiClient {
public OaiResponse<List<OaiSet>> listSets(final String baseUrl, final String resumptionToken) throws Exception {
final OaiRequest req = StringUtils.isNotBlank(resumptionToken)
? OaiRequest.newListSetsWithToken(baseUrl, resumptionToken)
: OaiRequest.newListSets(baseUrl);
final OaiResponse<List<OaiSet>> res = new OaiResponse<>();
callOaiVerb(req, res, doc -> doc
.selectNodes("//*[local-name()='ListSets']/*[local-name()='set']")
.stream()
.map(node -> (Element) node)
.map(OaiSetImpl::new)
.map(set -> (OaiSet) set)
.toList());
return res;
}
public OaiResponse<List<OaiMetadataFormat>> listMetadataFormats(final String baseUrl) throws Exception {
final OaiRequest req = OaiRequest.newListMetadataFormats(baseUrl);
final OaiResponse<List<OaiMetadataFormat>> res = new OaiResponse<>();
callOaiVerb(req, res, doc -> doc
.selectNodes("//*[local-name()='ListMetadataFormats']/*[local-name()='metadataFormat']")
.stream()
.map(node -> (Element) node)
.map(OaiMetadataFormatImpl::new)
.map(set -> (OaiMetadataFormat) set)
.toList());
return res;
}
public OaiResponse<List<OaiRecord<String, String>>> listRecords(final String baseUrl, final String mdPrefix, final String set, final String resumptionToken)
throws Exception {
final OaiRequest req = StringUtils.isNotBlank(resumptionToken)
? OaiRequest.newListRecordsWithToken(baseUrl, resumptionToken)
: OaiRequest.newListRecords(baseUrl, mdPrefix, set);
final OaiResponse<List<OaiRecord<String, String>>> res = new OaiResponse<>();
callOaiVerb(req, res, doc -> doc
.selectNodes("//*[local-name()='ListRecords']/*[local-name()='record']")
.stream()
.map(node -> (Element) node)
.map(OaiRecordImpl::new)
.map(r -> (OaiRecord<String, String>) r)
.toList());
return res;
}
public OaiResponse<List<OaiIdentifier<String>>> listIdentifiers(final String baseUrl, final String mdPrefix, final String set, final String resumptionToken)
throws Exception {
final OaiRequest req = StringUtils.isNotBlank(resumptionToken)
? OaiRequest.newListIdentifiersWithToken(baseUrl, resumptionToken)
: OaiRequest.newListIdentifiers(baseUrl, mdPrefix, set);
final OaiResponse<List<OaiIdentifier<String>>> res = new OaiResponse<>();
callOaiVerb(req, res, doc -> doc
.selectNodes("//*[local-name()='ListIdentifiers']/*[local-name()='header']")
.stream()
.map(node -> (Element) node)
.map(OaiIdentifierImpl::new)
.map(r -> (OaiIdentifier<String>) r)
.toList());
return res;
}
public OaiResponse<OaiRecord<String, String>> getRecord(final String baseUrl, final String mdPrefix, final String id) throws Exception {
final OaiRequest req = OaiRequest.newGetRecord(baseUrl, mdPrefix, id);
final OaiResponse<OaiRecord<String, String>> res = new OaiResponse<>();
callOaiVerb(req, res, doc -> doc
.selectNodes("//*[local-name()='GetRecord']/*[local-name()='record']")
.stream()
.map(node -> (Element) node)
.map(OaiRecordImpl::new)
.map(r -> (OaiRecord<String, String>) r)
.findFirst()
.orElseThrow());
return res;
}
public OaiResponse<OaiInfo<String>> info(final String baseUrl) throws Exception {
final OaiRequest req = OaiRequest.newIdentify(baseUrl);
final OaiResponse<OaiInfo<String>> res = new OaiResponse<>();
callOaiVerb(req, res, doc -> doc
.selectNodes("//*[local-name()='Identify']")
.stream()
.map(node -> (Element) node)
.map(OaiInfoImpl::new)
.map(r -> (OaiInfo<String>) r)
.findFirst()
.orElseThrow());
return res;
}
private <T> void callOaiVerb(final OaiRequest req, final OaiResponse<T> res, final Function<Document, T> processBody) {
final long start = System.currentTimeMillis();
try {
res.setVerb(req.getVerb());
final UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromHttpUrl(req.getBaseUrl());
req.toQueryParams().forEach((k, v) -> urlBuilder.queryParam(k, v));
final String url = urlBuilder.encode().toUriString();
res.setUrl(url);
final ResponseEntity<String> httpResponse = new RestTemplate().getForEntity(url, String.class);
res.setHttpCode(httpResponse.getStatusCode().value());
if (httpResponse.getStatusCode().isError()) {
res.setValid(false);
res.setError("ERROR: " + httpResponse.getStatusCode().value());
} else {
final Document doc = DocumentHelper.parseText(httpResponse.getBody());
final Node node = doc.selectSingleNode("//*[local-name() = 'resumptionToken']");
if (node != null) {
res.setSize(doc.selectNodes("//*[local-name()='" + req.getVerb() + "']/*[local-name() != 'resumptionToken']").size());
res.setCursor(NumberUtils.toInt(node.valueOf("@cursor"), -1));
res.setTotal(NumberUtils.toInt(node.valueOf("@completeListSize"), -1));
res.setResumptionToken(node.getText());
}
res.setBody(processBody.apply(doc));
res.setValid(true);
}
} catch (final Throwable e) {
res.setValid(false);
res.setError(e.getMessage());
} finally {
res.setTime(System.currentTimeMillis() - start);
}
}
}