forked from D-Net/dnet-hadoop
Merge pull request 'relation-from-odf' (#251) from relation-from-odf into beta
Reviewed-on: D-Net/dnet-hadoop#251
This commit is contained in:
commit
de7bc9350e
|
@ -30,6 +30,7 @@ import eu.dnetlib.dhp.schema.common.ModelSupport;
|
||||||
import eu.dnetlib.dhp.schema.oaf.*;
|
import eu.dnetlib.dhp.schema.oaf.*;
|
||||||
import eu.dnetlib.dhp.schema.oaf.utils.IdentifierFactory;
|
import eu.dnetlib.dhp.schema.oaf.utils.IdentifierFactory;
|
||||||
import eu.dnetlib.dhp.schema.oaf.utils.OafMapperUtils;
|
import eu.dnetlib.dhp.schema.oaf.utils.OafMapperUtils;
|
||||||
|
import eu.dnetlib.dhp.schema.oaf.utils.PidType;
|
||||||
|
|
||||||
public abstract class AbstractMdRecordToOafMapper {
|
public abstract class AbstractMdRecordToOafMapper {
|
||||||
|
|
||||||
|
@ -68,6 +69,17 @@ public abstract class AbstractMdRecordToOafMapper {
|
||||||
nsContext.put("datacite", DATACITE_SCHEMA_KERNEL_3);
|
nsContext.put("datacite", DATACITE_SCHEMA_KERNEL_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lowercase pidTypes as keys, normal casing for the values
|
||||||
|
protected static final Map<String, String> pidTypeWithAuthority = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
IdentifierFactory.PID_AUTHORITY
|
||||||
|
.keySet()
|
||||||
|
.stream()
|
||||||
|
.forEach(entry -> pidTypeWithAuthority.put(entry.toString().toLowerCase(), entry.toString()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
protected AbstractMdRecordToOafMapper(final VocabularyGroup vocs, final boolean invisible,
|
protected AbstractMdRecordToOafMapper(final VocabularyGroup vocs, final boolean invisible,
|
||||||
final boolean shouldHashId, final boolean forceOriginalId) {
|
final boolean shouldHashId, final boolean forceOriginalId) {
|
||||||
this.vocs = vocs;
|
this.vocs = vocs;
|
||||||
|
|
|
@ -22,9 +22,12 @@ import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import eu.dnetlib.dhp.common.PacePerson;
|
import eu.dnetlib.dhp.common.PacePerson;
|
||||||
import eu.dnetlib.dhp.common.vocabulary.VocabularyGroup;
|
import eu.dnetlib.dhp.common.vocabulary.VocabularyGroup;
|
||||||
|
import eu.dnetlib.dhp.schema.common.ModelSupport;
|
||||||
|
import eu.dnetlib.dhp.schema.common.RelationInverse;
|
||||||
import eu.dnetlib.dhp.schema.oaf.*;
|
import eu.dnetlib.dhp.schema.oaf.*;
|
||||||
import eu.dnetlib.dhp.schema.oaf.utils.CleaningFunctions;
|
import eu.dnetlib.dhp.schema.oaf.utils.CleaningFunctions;
|
||||||
import eu.dnetlib.dhp.schema.oaf.utils.IdentifierFactory;
|
import eu.dnetlib.dhp.schema.oaf.utils.IdentifierFactory;
|
||||||
|
import eu.dnetlib.dhp.schema.oaf.utils.PidType;
|
||||||
|
|
||||||
public class OdfToOafMapper extends AbstractMdRecordToOafMapper {
|
public class OdfToOafMapper extends AbstractMdRecordToOafMapper {
|
||||||
|
|
||||||
|
@ -393,40 +396,53 @@ public class OdfToOafMapper extends AbstractMdRecordToOafMapper {
|
||||||
final List<Oaf> res = new ArrayList<>();
|
final List<Oaf> res = new ArrayList<>();
|
||||||
|
|
||||||
for (final Object o : doc
|
for (final Object o : doc
|
||||||
.selectNodes("//*[local-name()='relatedIdentifier' and ./@relatedIdentifierType='OPENAIRE']")) {
|
.selectNodes("//*[local-name()='relatedIdentifier']")) {
|
||||||
|
|
||||||
final String originalId = ((Node) o).getText();
|
final String originalId = ((Node) o).getText().trim();
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(originalId)) {
|
if (StringUtils.isNotBlank(originalId)) {
|
||||||
final String otherId = createOpenaireId(50, originalId, false);
|
final String idType = ((Node) o).valueOf("@relatedIdentifierType");
|
||||||
final String type = ((Node) o).valueOf("@relationType");
|
final String relType = ((Node) o).valueOf("@relationType");
|
||||||
|
String otherId = guessRelatedIdentifier(idType, originalId);
|
||||||
if (type.equalsIgnoreCase(IS_SUPPLEMENT_TO)) {
|
if (StringUtils.isNotBlank(otherId)) {
|
||||||
res
|
res.addAll(getRelations(relType, docId, otherId, entity));
|
||||||
.add(
|
|
||||||
getRelation(
|
|
||||||
docId, otherId, RESULT_RESULT, SUPPLEMENT, IS_SUPPLEMENT_TO, entity));
|
|
||||||
res
|
|
||||||
.add(
|
|
||||||
getRelation(
|
|
||||||
otherId, docId, RESULT_RESULT, SUPPLEMENT, IS_SUPPLEMENTED_BY, entity));
|
|
||||||
} else if (type.equalsIgnoreCase(IS_PART_OF)) {
|
|
||||||
res
|
|
||||||
.add(
|
|
||||||
getRelation(
|
|
||||||
docId, otherId, RESULT_RESULT, PART, IS_PART_OF, entity));
|
|
||||||
res
|
|
||||||
.add(
|
|
||||||
getRelation(
|
|
||||||
otherId, docId, RESULT_RESULT, PART, HAS_PART, entity));
|
|
||||||
} else {
|
|
||||||
// TODO catch more semantics
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String guessRelatedIdentifier(final String idType, final String value) {
|
||||||
|
if (StringUtils.isBlank(idType) || StringUtils.isBlank(value))
|
||||||
|
return null;
|
||||||
|
if (idType.equalsIgnoreCase("OPENAIRE"))
|
||||||
|
return createOpenaireId(50, value, false);
|
||||||
|
if (pidTypeWithAuthority.containsKey(idType.toLowerCase())) {
|
||||||
|
return IdentifierFactory.idFromPid("50", pidTypeWithAuthority.get(idType.toLowerCase()), value, true);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<Oaf> getRelations(final String reltype, final String entityId, final String otherId,
|
||||||
|
final OafEntity entity) {
|
||||||
|
final List<Oaf> res = new ArrayList<>();
|
||||||
|
RelationInverse rel = ModelSupport.findRelation(reltype);
|
||||||
|
if (rel != null) {
|
||||||
|
res
|
||||||
|
.add(
|
||||||
|
getRelation(
|
||||||
|
entityId, otherId, rel.getRelType(), rel.getSubReltype(), rel.getRelClass(), entity));
|
||||||
|
res
|
||||||
|
.add(
|
||||||
|
getRelation(
|
||||||
|
otherId, entityId, rel.getRelType(), rel.getSubReltype(), rel.getInverseRelClass(), entity));
|
||||||
|
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Qualifier prepareResourceType(final Document doc, final DataInfo info) {
|
protected Qualifier prepareResourceType(final Document doc, final DataInfo info) {
|
||||||
return prepareQualifier(
|
return prepareQualifier(
|
||||||
|
|
|
@ -579,8 +579,10 @@ class MappersTest {
|
||||||
|
|
||||||
final List<Oaf> list = new OdfToOafMapper(vocs, false, true).processMdRecord(xml);
|
final List<Oaf> list = new OdfToOafMapper(vocs, false, true).processMdRecord(xml);
|
||||||
|
|
||||||
assertEquals(1, list.size());
|
assertEquals(3, list.size());
|
||||||
assertTrue(list.get(0) instanceof Software);
|
assertTrue(list.get(0) instanceof Software);
|
||||||
|
assertTrue(list.get(1) instanceof Relation);
|
||||||
|
assertTrue(list.get(2) instanceof Relation);
|
||||||
|
|
||||||
final Software s = (Software) list.get(0);
|
final Software s = (Software) list.get(0);
|
||||||
|
|
||||||
|
@ -590,6 +592,22 @@ class MappersTest {
|
||||||
assertTrue(s.getAuthor().size() > 0);
|
assertTrue(s.getAuthor().size() > 0);
|
||||||
assertTrue(s.getSubject().size() > 0);
|
assertTrue(s.getSubject().size() > 0);
|
||||||
assertTrue(s.getInstance().size() > 0);
|
assertTrue(s.getInstance().size() > 0);
|
||||||
|
|
||||||
|
final Relation r1 = (Relation) list.get(1);
|
||||||
|
final Relation r2 = (Relation) list.get(2);
|
||||||
|
|
||||||
|
assertEquals(s.getId(), r1.getSource());
|
||||||
|
assertEquals("50|doi_________::b453e7b4b2130ace57ff0c3db470a982", r1.getTarget());
|
||||||
|
assertEquals(ModelConstants.RESULT_RESULT, r1.getRelType());
|
||||||
|
assertEquals(ModelConstants.RELATIONSHIP, r1.getSubRelType());
|
||||||
|
assertEquals(ModelConstants.IS_REFERENCED_BY, r1.getRelClass());
|
||||||
|
|
||||||
|
assertEquals(s.getId(), r2.getTarget());
|
||||||
|
assertEquals("50|doi_________::b453e7b4b2130ace57ff0c3db470a982", r2.getSource());
|
||||||
|
assertEquals(ModelConstants.RESULT_RESULT, r2.getRelType());
|
||||||
|
assertEquals(ModelConstants.RELATIONSHIP, r2.getSubRelType());
|
||||||
|
assertEquals(ModelConstants.REFERENCES, r2.getRelClass());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -912,13 +930,13 @@ class MappersTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testROHub() throws IOException, DocumentException {
|
void testROHub() throws IOException {
|
||||||
final String xml = IOUtils.toString(Objects.requireNonNull(getClass().getResourceAsStream("rohub.xml")));
|
final String xml = IOUtils.toString(Objects.requireNonNull(getClass().getResourceAsStream("rohub.xml")));
|
||||||
final List<Oaf> list = new OdfToOafMapper(vocs, false, true).processMdRecord(xml);
|
final List<Oaf> list = new OdfToOafMapper(vocs, false, true).processMdRecord(xml);
|
||||||
System.out.println("***************");
|
System.out.println("***************");
|
||||||
System.out.println(new ObjectMapper().writeValueAsString(list));
|
System.out.println(new ObjectMapper().writeValueAsString(list));
|
||||||
System.out.println("***************");
|
System.out.println("***************");
|
||||||
// final Dataset p = (Dataset) list.get(0);
|
// final OtherResearchProduct p = (OtherResearchProduct) list.get(0);
|
||||||
// assertValidId(p.getId());
|
// assertValidId(p.getId());
|
||||||
// assertValidId(p.getCollectedfrom().get(0).getKey());
|
// assertValidId(p.getCollectedfrom().get(0).getKey());
|
||||||
// System.out.println(p.getTitle().get(0).getValue());
|
// System.out.println(p.getTitle().get(0).getValue());
|
||||||
|
@ -926,13 +944,36 @@ class MappersTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testROHub2() throws IOException, DocumentException {
|
void testROHub2() throws IOException {
|
||||||
final String xml = IOUtils
|
final String xml = IOUtils
|
||||||
.toString(Objects.requireNonNull(getClass().getResourceAsStream("rohub-modified.xml")));
|
.toString(Objects.requireNonNull(getClass().getResourceAsStream("rohub-modified.xml")));
|
||||||
final List<Oaf> list = new OdfToOafMapper(vocs, false, true).processMdRecord(xml);
|
final List<Oaf> list = new OdfToOafMapper(vocs, false, true).processMdRecord(xml);
|
||||||
System.out.println("***************");
|
System.out.println("***************");
|
||||||
System.out.println(new ObjectMapper().writeValueAsString(list));
|
System.out.println(new ObjectMapper().writeValueAsString(list));
|
||||||
System.out.println("***************");
|
System.out.println("***************");
|
||||||
|
assertEquals(7, list.size());
|
||||||
|
final OtherResearchProduct p = (OtherResearchProduct) list.get(0);
|
||||||
|
assertValidId(p.getId());
|
||||||
|
assertValidId(p.getCollectedfrom().get(0).getKey());
|
||||||
|
assertEquals("50|w3id________::afc7592914ae190a50570db90f55f9c2", p.getId());
|
||||||
|
assertTrue(StringUtils.isNotBlank(p.getTitle().get(0).getValue()));
|
||||||
|
assertEquals("w3id", (p.getPid().get(0).getQualifier().getClassid()));
|
||||||
|
assertEquals("https://w3id.org/ro-id/0ab171a7-45c5-4194-82d4-850955504bca", (p.getPid().get(0).getValue()));
|
||||||
|
|
||||||
|
assertEquals(1, list.stream().filter(o -> o instanceof OtherResearchProduct).count());
|
||||||
|
assertEquals(6, list.stream().filter(o -> o instanceof Relation).count());
|
||||||
|
|
||||||
|
for (Oaf oaf : list) {
|
||||||
|
if (oaf instanceof Relation) {
|
||||||
|
String source = ((Relation) oaf).getSource();
|
||||||
|
String target = ((Relation) oaf).getTarget();
|
||||||
|
assertNotEquals(source, target);
|
||||||
|
assertTrue(source.equals(p.getId()) || target.equals(p.getId()));
|
||||||
|
assertNotNull(((Relation) oaf).getSubRelType());
|
||||||
|
assertNotNull(((Relation) oaf).getRelClass());
|
||||||
|
assertNotNull(((Relation) oaf).getRelType());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -69,7 +69,6 @@
|
||||||
</dates>
|
</dates>
|
||||||
<resourceType resourceTypeGeneral="Dataset"/>
|
<resourceType resourceTypeGeneral="Dataset"/>
|
||||||
<relatedIdentifiers>
|
<relatedIdentifiers>
|
||||||
<relatedIdentifier relatedIdentifierType="DOI" relationType="IsVersionOf">10.5281/zenodo.3234525</relatedIdentifier>
|
|
||||||
<relatedIdentifier relatedIdentifierType="URL" relationType="IsPartOf">https://zenodo.org/communities/epfl</relatedIdentifier>
|
<relatedIdentifier relatedIdentifierType="URL" relationType="IsPartOf">https://zenodo.org/communities/epfl</relatedIdentifier>
|
||||||
</relatedIdentifiers>
|
</relatedIdentifiers>
|
||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<datacite:publisher>bio.tools</datacite:publisher>
|
<datacite:publisher>bio.tools</datacite:publisher>
|
||||||
<datacite:relatedIdentifiers>
|
<datacite:relatedIdentifiers>
|
||||||
<datacite:relatedIdentifier relatedIdentifierType="URL" relationType="IsDocumentedBy">http://maplab.imppc.org/chainy/</datacite:relatedIdentifier>
|
<datacite:relatedIdentifier relatedIdentifierType="URL" relationType="IsDocumentedBy">http://maplab.imppc.org/chainy/</datacite:relatedIdentifier>
|
||||||
<datacite:relatedIdentifier relatedIdentifierType="DOI" relationType="isReferencedBy">10.1093/bioinformatics/btw839</datacite:relatedIdentifier>
|
<datacite:relatedIdentifier relatedIdentifierType="DOI" relationType="isreferencedBy">10.1093/bioinformatics/btw839</datacite:relatedIdentifier>
|
||||||
</datacite:relatedIdentifiers>
|
</datacite:relatedIdentifiers>
|
||||||
<datacite:alternateIdentifiers>
|
<datacite:alternateIdentifiers>
|
||||||
<datacite:alternateIdentifier alternateIdentifierType="LandingPage">https://bio.tools/</datacite:alternateIdentifier>
|
<datacite:alternateIdentifier alternateIdentifierType="LandingPage">https://bio.tools/</datacite:alternateIdentifier>
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
<datacite:relatedIdentifier relatedIdentifierType="w3id" relationType="HasPart">
|
<datacite:relatedIdentifier relatedIdentifierType="w3id" relationType="HasPart">
|
||||||
https://w3id.org/ro-id/0ab171a7-45c5-4194-82d4-850955504bca/resources/6d3427a8-352e-49f4-9796-f618c44dc16d
|
https://w3id.org/ro-id/0ab171a7-45c5-4194-82d4-850955504bca/resources/6d3427a8-352e-49f4-9796-f618c44dc16d
|
||||||
</datacite:relatedIdentifier>
|
</datacite:relatedIdentifier>
|
||||||
|
<datacite:relatedIdentifier relatedIdentifierType="OPENAIRE" relationType="isSupplementedBy">
|
||||||
|
fsh_____4119::afc7592914ae190a50570db90f55f9c3
|
||||||
|
</datacite:relatedIdentifier>
|
||||||
</datacite:relatedIdentifiers>
|
</datacite:relatedIdentifiers>
|
||||||
<datacite:resourceType xs:anyURI="http://purl.org/coar/resource_type/c_1843">RO-crate</datacite:resourceType>
|
<datacite:resourceType xs:anyURI="http://purl.org/coar/resource_type/c_1843">RO-crate</datacite:resourceType>
|
||||||
<datacite:rightsList>
|
<datacite:rightsList>
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -807,7 +807,7 @@
|
||||||
<mockito-core.version>3.3.3</mockito-core.version>
|
<mockito-core.version>3.3.3</mockito-core.version>
|
||||||
<mongodb.driver.version>3.4.2</mongodb.driver.version>
|
<mongodb.driver.version>3.4.2</mongodb.driver.version>
|
||||||
<vtd.version>[2.12,3.0)</vtd.version>
|
<vtd.version>[2.12,3.0)</vtd.version>
|
||||||
<dhp-schemas.version>[3.14.0]</dhp-schemas.version>
|
<dhp-schemas.version>[3.15.0]</dhp-schemas.version>
|
||||||
<dnet-actionmanager-api.version>[4.0.3]</dnet-actionmanager-api.version>
|
<dnet-actionmanager-api.version>[4.0.3]</dnet-actionmanager-api.version>
|
||||||
<dnet-actionmanager-common.version>[6.0.5]</dnet-actionmanager-common.version>
|
<dnet-actionmanager-common.version>[6.0.5]</dnet-actionmanager-common.version>
|
||||||
<dnet-openaire-broker-common.version>[3.1.6]</dnet-openaire-broker-common.version>
|
<dnet-openaire-broker-common.version>[3.1.6]</dnet-openaire-broker-common.version>
|
||||||
|
|
Loading…
Reference in New Issue