From d8882c4481812856b8bc476c27f615c21a1eecae Mon Sep 17 00:00:00 2001 From: Claudio Atzori Date: Tue, 2 May 2023 11:56:51 +0200 Subject: [PATCH] extended mapping applied to datacite records to produce affiliations using the ROR ids. Inc ase of APCs it includes the amount and the currently in the relation --- .../raw/AbstractMdRecordToOafMapper.java | 58 +++++++++++++++---- .../dnetlib/dhp/oa/graph/raw/MappersTest.java | 42 +++++++++++++- 2 files changed, 87 insertions(+), 13 deletions(-) diff --git a/dhp-workflows/dhp-graph-mapper/src/main/java/eu/dnetlib/dhp/oa/graph/raw/AbstractMdRecordToOafMapper.java b/dhp-workflows/dhp-graph-mapper/src/main/java/eu/dnetlib/dhp/oa/graph/raw/AbstractMdRecordToOafMapper.java index 7aa40cb8a..cb9447b1b 100644 --- a/dhp-workflows/dhp-graph-mapper/src/main/java/eu/dnetlib/dhp/oa/graph/raw/AbstractMdRecordToOafMapper.java +++ b/dhp-workflows/dhp-graph-mapper/src/main/java/eu/dnetlib/dhp/oa/graph/raw/AbstractMdRecordToOafMapper.java @@ -1,14 +1,9 @@ package eu.dnetlib.dhp.oa.graph.raw; -import static eu.dnetlib.dhp.schema.common.ModelConstants.DNET_PID_TYPES; -import static eu.dnetlib.dhp.schema.common.ModelConstants.IS_PRODUCED_BY; -import static eu.dnetlib.dhp.schema.common.ModelConstants.OUTCOME; -import static eu.dnetlib.dhp.schema.common.ModelConstants.PRODUCES; -import static eu.dnetlib.dhp.schema.common.ModelConstants.REPOSITORY_PROVENANCE_ACTIONS; -import static eu.dnetlib.dhp.schema.common.ModelConstants.RESULT_PROJECT; -import static eu.dnetlib.dhp.schema.common.ModelConstants.UNKNOWN; +import static eu.dnetlib.dhp.schema.common.ModelConstants.*; import static eu.dnetlib.dhp.schema.oaf.utils.OafMapperUtils.*; +import static eu.dnetlib.dhp.schema.oaf.utils.OafMapperUtils.createOpenaireId; import java.net.MalformedURLException; import java.net.URL; @@ -22,6 +17,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import com.google.common.collect.Sets; import eu.dnetlib.dhp.common.vocabulary.VocabularyGroup; @@ -195,6 +191,7 @@ public abstract class AbstractMdRecordToOafMapper { rels.addAll(addProjectRels(doc, entity)); rels.addAll(addOtherResultRels(doc, entity)); rels.addAll(addRelations(doc, entity)); + rels.addAll(addAffiliations(doc, entity)); oafs.addAll(rels); } @@ -295,7 +292,7 @@ public abstract class AbstractMdRecordToOafMapper { final String relClassInverse = ModelSupport .findInverse(ModelSupport.rel(relType, subRelType, relClass)) .getInverseRelClass(); - final String validationdDate = ((Node) o).valueOf("@validationDate"); + final String validationDate = ((Node) o).valueOf("@validationDate"); if (StringUtils.isNotBlank(target)) { final String targetType = element.attributeValue("targetType"); @@ -306,13 +303,13 @@ public abstract class AbstractMdRecordToOafMapper { OafMapperUtils .getRelation( entity.getId(), targetId, relType, subRelType, relClass, entity, - validationdDate)); + validationDate)); rels .add( OafMapperUtils .getRelation( targetId, entity.getId(), relType, subRelType, relClassInverse, entity, - validationdDate)); + validationDate)); } } } @@ -320,6 +317,47 @@ public abstract class AbstractMdRecordToOafMapper { return rels; } + private List addAffiliations(Document doc, OafEntity entity) { + final List rels = Lists.newArrayList(); + + for (Object o : doc.selectNodes("//datacite:affiliation[@affiliationIdentifierScheme='ROR']")) { + Element element = (Element) o; + + String rorId = element.attributeValue("affiliationIdentifier"); + if (StringUtils.isNotBlank(rorId)) { + + String resultId = entity.getId(); + String orgId = createOpenaireId("organization", rorId, true); + + List properties = Lists.newArrayList(); + + String apcAmount = doc.valueOf("//oaf:processingchargeamount"); + String apcCurrency = doc.valueOf("//oaf:processingchargeamount/@currency"); + + if (StringUtils.isNotBlank(apcAmount) && StringUtils.isNotBlank(apcCurrency)) { + properties.add(OafMapperUtils.keyValue("apc_amount", apcAmount)); + properties.add(OafMapperUtils.keyValue("apc_currency", apcCurrency)); + } + + rels + .add( + OafMapperUtils + .getRelation( + resultId, orgId, RESULT_ORGANIZATION, AFFILIATION, HAS_AUTHOR_INSTITUTION, + entity.getCollectedfrom(), entity.getDataInfo(), entity.getLastupdatetimestamp(), null, + properties)); + rels + .add( + OafMapperUtils + .getRelation( + orgId, resultId, RESULT_ORGANIZATION, AFFILIATION, IS_AUTHOR_INSTITUTION_OF, + entity.getCollectedfrom(), entity.getDataInfo(), entity.getLastupdatetimestamp(), null, + properties)); + } + } + return rels; + } + protected abstract List addOtherResultRels( final Document doc, final OafEntity entity); diff --git a/dhp-workflows/dhp-graph-mapper/src/test/java/eu/dnetlib/dhp/oa/graph/raw/MappersTest.java b/dhp-workflows/dhp-graph-mapper/src/test/java/eu/dnetlib/dhp/oa/graph/raw/MappersTest.java index d08545388..81daeb373 100644 --- a/dhp-workflows/dhp-graph-mapper/src/test/java/eu/dnetlib/dhp/oa/graph/raw/MappersTest.java +++ b/dhp-workflows/dhp-graph-mapper/src/test/java/eu/dnetlib/dhp/oa/graph/raw/MappersTest.java @@ -930,16 +930,52 @@ class MappersTest { System.out.println(new ObjectMapper().writeValueAsString(list)); System.out.println("***************"); - final Publication p = (Publication) list.get(0); + final Optional o = list.stream().filter(r -> r instanceof Publication).findFirst(); + assertTrue(o.isPresent()); + + Publication p = (Publication) o.get(); assertTrue(p.getInstance().size() > 0); assertEquals("https://doi.org/10.1155/2015/439379", p.getInstance().get(0).getUrl().get(0)); - assertTrue(p.getProcessingchargeamount() != null); - assertTrue(p.getProcessingchargecurrency() != null); + assertNotNull(p.getProcessingchargeamount()); + assertNotNull(p.getProcessingchargecurrency()); assertEquals("1721.47", p.getProcessingchargeamount().getValue()); assertEquals("EUR", p.getProcessingchargecurrency().getValue()); + + List affiliations = list.stream().filter(r -> r instanceof Relation).collect(Collectors.toList()); + assertEquals(2, affiliations.size()); + + for (Oaf aff : affiliations) { + Relation r = (Relation) aff; + assertEquals(ModelConstants.AFFILIATION, r.getSubRelType()); + assertEquals(ModelConstants.RESULT_ORGANIZATION, r.getRelType()); + String source = r.getSource(); + if (StringUtils.startsWith(source, "50")) { + assertEquals(ModelConstants.HAS_AUTHOR_INSTITUTION, r.getRelClass()); + } else if (StringUtils.startsWith(source, "20")) { + assertEquals(ModelConstants.IS_AUTHOR_INSTITUTION_OF, r.getRelClass()); + } else { + throw new IllegalArgumentException("invalid source / target prefixes for affiliation relations"); + } + + List apcInfo = r.getProperties(); + assertEquals( + "EUR", apcInfo + .stream() + .filter(kv -> "apc_currency".equals(kv.getKey())) + .map(KeyValue::getValue) + .findFirst() + .orElse("")); + assertEquals( + "1721.47", apcInfo + .stream() + .filter(kv -> "apc_amount".equals(kv.getKey())) + .map(KeyValue::getValue) + .findFirst() + .orElse("")); + } } @Test