diff --git a/pom.xml b/pom.xml index ce1de76..052b1bd 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,7 @@ 1.9.4 3.1.0 1.27.1 + 4.1.115.Final 2.1.3 4.0.2 5.2.0 @@ -87,8 +88,15 @@ org.gbif dwca-io ${dwca-io.version} + + + + commons-io + commons-io + + - + commons-beanutils commons-beanutils @@ -100,6 +108,12 @@ commons-compress ${commons-compress.version} + + + io.netty + netty-common + ${netty-common.version} + org.codehaus.mojo jaxb2-maven-plugin diff --git a/src/main/java/eu/dissco/core/translator/service/DwcaService.java b/src/main/java/eu/dissco/core/translator/service/DwcaService.java index ce2ba8a..304f645 100644 --- a/src/main/java/eu/dissco/core/translator/service/DwcaService.java +++ b/src/main/java/eu/dissco/core/translator/service/DwcaService.java @@ -137,7 +137,7 @@ public void getSpecimenData(Set ids, Archive archive, AtomicInteger proc var specimenData = dwcaRepository.getCoreRecords(batch, getTableName(archive.getCore())); log.info("Got specimen batch: {}", batch.size()); addExtensionsToSpecimen(archive, batch, specimenData); - log.info("Start translation and publishing of batch: {}", specimenData.values().size()); + log.info("Start translation and publishing of batch: {}", specimenData.size()); processDigitalSpecimen(specimenData.values(), optionalEmlData, processedRecords); } } catch (ReachedMaximumLimitException e) { diff --git a/src/main/java/eu/dissco/core/translator/terms/BaseDigitalObjectDirector.java b/src/main/java/eu/dissco/core/translator/terms/BaseDigitalObjectDirector.java index e957f52..e7a0c7a 100644 --- a/src/main/java/eu/dissco/core/translator/terms/BaseDigitalObjectDirector.java +++ b/src/main/java/eu/dissco/core/translator/terms/BaseDigitalObjectDirector.java @@ -2,7 +2,6 @@ import static eu.dissco.core.translator.domain.AgentRoleType.COLLECTOR; import static eu.dissco.core.translator.domain.AgentRoleType.CREATOR; -import static eu.dissco.core.translator.domain.AgentRoleType.DATA_TRANSLATOR; import static eu.dissco.core.translator.domain.AgentRoleType.GEOREFERENCER; import static eu.dissco.core.translator.domain.AgentRoleType.IDENTIFIER; import static eu.dissco.core.translator.domain.AgentRoleType.RIGHTS_OWNER; @@ -15,14 +14,13 @@ import static eu.dissco.core.translator.domain.RelationshipType.HAS_SOURCE_SYSTEM_ID; import static eu.dissco.core.translator.domain.RelationshipType.HAS_URL; import static eu.dissco.core.translator.schema.Agent.Type.SCHEMA_PERSON; -import static eu.dissco.core.translator.schema.Agent.Type.SCHEMA_SOFTWARE_APPLICATION; import static eu.dissco.core.translator.terms.utils.AgentsUtils.addAgent; +import static eu.dissco.core.translator.terms.utils.EntityRelationshipUtils.addEntityRelationship; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import eu.dissco.core.translator.component.OrganisationNameComponent; import eu.dissco.core.translator.component.SourceSystemComponent; -import eu.dissco.core.translator.domain.RelationshipType; import eu.dissco.core.translator.exception.OrganisationException; import eu.dissco.core.translator.exception.UnknownPhysicalSpecimenIdType; import eu.dissco.core.translator.properties.FdoProperties; @@ -235,7 +233,6 @@ import eu.dissco.core.translator.terms.specimen.stratigraphy.lithostratigraphic.Group; import eu.dissco.core.translator.terms.specimen.stratigraphy.lithostratigraphic.LithostratigraphicTerms; import eu.dissco.core.translator.terms.specimen.stratigraphy.lithostratigraphic.Member; -import java.time.Instant; import java.util.ArrayList; import java.util.List; import lombok.RequiredArgsConstructor; @@ -362,38 +359,32 @@ private String getOrganisationName(String organisationId) throws OrganisationExc private List assembleDigitalSpecimenEntityRelationships( DigitalSpecimen ds) { var relationships = new ArrayList(); - relationships.add(getEntityRelationship(HAS_ORGANISATION_ID, ds.getOdsOrganisationID())); - relationships.add(getEntityRelationship(HAS_SOURCE_SYSTEM_ID, ds.getOdsSourceSystemID())); - relationships.add(getEntityRelationship(HAS_FDO_TYPE, fdoProperties.getDigitalSpecimenType())); + relationships.add(addEntityRelationship(HAS_ORGANISATION_ID, ds.getOdsOrganisationID(), + fdoProperties.getApplicationName(), fdoProperties.getApplicationPID())); + relationships.add(addEntityRelationship(HAS_SOURCE_SYSTEM_ID, ds.getOdsSourceSystemID(), + fdoProperties.getApplicationName(), fdoProperties.getApplicationPID())); + relationships.add(addEntityRelationship(HAS_FDO_TYPE, fdoProperties.getDigitalSpecimenType(), + fdoProperties.getApplicationName(), fdoProperties.getApplicationPID())); if (ds.getOdsPhysicalSpecimenIDType().equals(OdsPhysicalSpecimenIDType.RESOLVABLE)) { relationships.add( - getEntityRelationship(HAS_PHYSICAL_IDENTIFIER, ds.getOdsPhysicalSpecimenID())); + addEntityRelationship(HAS_PHYSICAL_IDENTIFIER, ds.getOdsPhysicalSpecimenID(), + fdoProperties.getApplicationName(), fdoProperties.getApplicationPID())); } if (ds.getDctermsLicense() != null && ds.getDctermsLicense().startsWith("http")) { - relationships.add(getEntityRelationship(HAS_LICENSE, ds.getDctermsLicense())); + relationships.add(addEntityRelationship(HAS_LICENSE, ds.getDctermsLicense(), + fdoProperties.getApplicationName(), fdoProperties.getApplicationPID())); } if (ds.getOdsHasCitations() != null) { for (Citation citation : ds.getOdsHasCitations()) { if (citation.getId() != null && citation.getId().startsWith("http")) { - relationships.add(getEntityRelationship(HAS_REFERENCE, citation.getId())); + relationships.add(addEntityRelationship(HAS_REFERENCE, citation.getId(), + fdoProperties.getApplicationName(), fdoProperties.getApplicationPID())); } } } return relationships; } - private EntityRelationship getEntityRelationship(RelationshipType relationshipType, - String relatedResource) { - var entityRelationship = new EntityRelationship() - .withType("ods:EntityRelationship") - .withDwcRelationshipOfResource(relationshipType.getName()) - .withDwcRelatedResourceID(relatedResource) - .withDwcRelationshipEstablishedDate(java.util.Date.from(Instant.now())); - entityRelationship.setOdsHasAgents(addAgent(entityRelationship.getOdsHasAgents(), fdoProperties.getApplicationName(), - fdoProperties.getApplicationPID(), DATA_TRANSLATOR, SCHEMA_SOFTWARE_APPLICATION)); - return entityRelationship; - } - private List assembleIdentifiers(JsonNode data) { var identifiers = new ArrayList(); for (String identifierTerm : identifierTerms) { @@ -461,7 +452,8 @@ protected Identification createIdentification(JsonNode data, boolean dwc) { termMapper.retrieveTerm(new VerbatimIdentification(), data, dwc)) .withOdsHasTaxonIdentifications(List.of(mappedTaxonIdentification)) .withOdsHasCitations(assembleIdentificationCitations(data, dwc)); - identification.setOdsHasAgents(addAgent(identification.getOdsHasAgents(), termMapper.retrieveTerm(new IdentifiedBy(), data, dwc), + identification.setOdsHasAgents(addAgent(identification.getOdsHasAgents(), + termMapper.retrieveTerm(new IdentifiedBy(), data, dwc), termMapper.retrieveTerm(new IdentifiedByID(), data, dwc), IDENTIFIER, SCHEMA_PERSON)); return identification; } @@ -590,8 +582,9 @@ private List assembleEventTerms(JsonNode data, boolean dwc) { .withDwcVitality(termMapper.retrieveTerm(new Vitality(), data, dwc)) .withOdsHasLocation(location) .withOdsHasAssertions(assertions); - event.setOdsHasAgents(addAgent(event.getOdsHasAgents(), termMapper.retrieveTerm(new RecordedBy(), data, dwc), - termMapper.retrieveTerm(new RecordedByID(), data, dwc), COLLECTOR, SCHEMA_PERSON)); + event.setOdsHasAgents( + addAgent(event.getOdsHasAgents(), termMapper.retrieveTerm(new RecordedBy(), data, dwc), + termMapper.retrieveTerm(new RecordedByID(), data, dwc), COLLECTOR, SCHEMA_PERSON)); return List.of(event); } @@ -714,19 +707,24 @@ public DigitalMedia assembleDigitalMedia(boolean dwc, JsonNode mediaRecord, private List assembleDigitalMediaEntityRelationships( DigitalMedia digitalMedia) { var relationships = new ArrayList(); - relationships.add(getEntityRelationship(HAS_URL, digitalMedia.getAcAccessURI())); + relationships.add(addEntityRelationship(HAS_URL, digitalMedia.getAcAccessURI(), + fdoProperties.getApplicationName(), fdoProperties.getApplicationPID())); relationships.add( - getEntityRelationship(HAS_ORGANISATION_ID, digitalMedia.getOdsOrganisationID())); + addEntityRelationship(HAS_ORGANISATION_ID, digitalMedia.getOdsOrganisationID(), + fdoProperties.getApplicationName(), fdoProperties.getApplicationPID())); relationships.add( - getEntityRelationship(HAS_FDO_TYPE, fdoProperties.getDigitalMediaType())); + addEntityRelationship(HAS_FDO_TYPE, fdoProperties.getDigitalMediaType(), + fdoProperties.getApplicationName(), fdoProperties.getApplicationPID())); if (digitalMedia.getDctermsRights() != null && digitalMedia.getDctermsRights() .startsWith("http")) { relationships.add( - getEntityRelationship(HAS_LICENSE, digitalMedia.getDctermsRights())); + addEntityRelationship(HAS_LICENSE, digitalMedia.getDctermsRights(), + fdoProperties.getApplicationName(), fdoProperties.getApplicationPID())); } if (digitalMedia.getDctermsSource() != null && digitalMedia.getDctermsSource() .startsWith("http")) { - relationships.add(getEntityRelationship(HAS_SOURCE, digitalMedia.getDctermsSource())); + relationships.add(addEntityRelationship(HAS_SOURCE, digitalMedia.getDctermsSource(), + fdoProperties.getApplicationName(), fdoProperties.getApplicationPID())); } return relationships; } diff --git a/src/main/java/eu/dissco/core/translator/terms/BiocaseDigitalObjectDirector.java b/src/main/java/eu/dissco/core/translator/terms/BiocaseDigitalObjectDirector.java index 9013737..b9160a3 100644 --- a/src/main/java/eu/dissco/core/translator/terms/BiocaseDigitalObjectDirector.java +++ b/src/main/java/eu/dissco/core/translator/terms/BiocaseDigitalObjectDirector.java @@ -24,7 +24,8 @@ public class BiocaseDigitalObjectDirector extends BaseDigitalObjectDirector { public BiocaseDigitalObjectDirector(ObjectMapper mapper, TermMapper termMapper, OrganisationNameComponent rorComponent, SourceSystemComponent sourceSystemComponent, FdoProperties fdoProperties) { - super(mapper, termMapper, rorComponent, sourceSystemComponent, fdoProperties, identifierTerms()); + super(mapper, termMapper, rorComponent, sourceSystemComponent, fdoProperties, + identifierTerms()); } private static List identifierTerms() { diff --git a/src/main/java/eu/dissco/core/translator/terms/DwcaDigitalObjectDirector.java b/src/main/java/eu/dissco/core/translator/terms/DwcaDigitalObjectDirector.java index 91f4878..aeaf37f 100644 --- a/src/main/java/eu/dissco/core/translator/terms/DwcaDigitalObjectDirector.java +++ b/src/main/java/eu/dissco/core/translator/terms/DwcaDigitalObjectDirector.java @@ -25,7 +25,8 @@ public class DwcaDigitalObjectDirector extends BaseDigitalObjectDirector { public DwcaDigitalObjectDirector(ObjectMapper mapper, TermMapper termMapper, OrganisationNameComponent rorComponent, SourceSystemComponent sourceSystemComponent, FdoProperties fdoProperties) { - super(mapper, termMapper, rorComponent, sourceSystemComponent, fdoProperties, identifierTerms()); + super(mapper, termMapper, rorComponent, sourceSystemComponent, fdoProperties, + identifierTerms()); } private static List identifierTerms() { @@ -52,7 +53,7 @@ protected List assembleSpecimenCitations(JsonNode data, boolean dwc) { var references = data.get(EXTENSION).get("gbif:Reference"); for (int i = 0; i < references.size(); i++) { var citationJson = references.get(i); - if (citationJson.properties().size() <= 1){ + if (citationJson.properties().size() <= 1) { log.debug("Skipping citation with only one property: {}", citationJson); } else { citations.add(createCitation(citationJson, dwc)); diff --git a/src/main/java/eu/dissco/core/translator/terms/media/MediaType.java b/src/main/java/eu/dissco/core/translator/terms/media/MediaType.java index 8b07282..78bb64a 100644 --- a/src/main/java/eu/dissco/core/translator/terms/media/MediaType.java +++ b/src/main/java/eu/dissco/core/translator/terms/media/MediaType.java @@ -12,9 +12,11 @@ public class MediaType extends Term { private static final String STILL_IMAGE = "Still_Image"; private static final String SOUND = "Sound"; private static final String MOVING_IMAGE = "Moving_Image"; + private static final String INTERACTIVE_RESOURCE = "Interactive_Resource"; private final List dwcaTerms = List.of(TERM, "dc:type"); private final List imageFormats = List.of("IMAGE/JPG", "JPG", "IMAGE/JPEG", "JPEG", "IMAGE/PNG", "PNG", "IMAGE/TIF", "TIF"); + private final List interactiveResourceFormats = List.of("APPLICATION/JSON"); @Override public String retrieveFromDWCA(JsonNode unit) { @@ -51,6 +53,8 @@ public String retrieveFromABCD(JsonNode unit) { format = format.toUpperCase(); if (imageFormats.contains(format)) { return STILL_IMAGE; + } else if (interactiveResourceFormats.contains(format)) { + return INTERACTIVE_RESOURCE; } else { log.warn("Unable to determine media type of digital media object"); return null; diff --git a/src/main/java/eu/dissco/core/translator/terms/specimen/DatasetID.java b/src/main/java/eu/dissco/core/translator/terms/specimen/DatasetID.java index f602d83..8235111 100644 --- a/src/main/java/eu/dissco/core/translator/terms/specimen/DatasetID.java +++ b/src/main/java/eu/dissco/core/translator/terms/specimen/DatasetID.java @@ -5,6 +5,7 @@ import java.util.List; public class DatasetID extends Term { + public static final String TERM = DWC_PREFIX + "datasetID"; private final List dwcaTerms = List.of(TERM); diff --git a/src/main/java/eu/dissco/core/translator/terms/specimen/DynamicProperties.java b/src/main/java/eu/dissco/core/translator/terms/specimen/DynamicProperties.java index 27b494e..2113b06 100644 --- a/src/main/java/eu/dissco/core/translator/terms/specimen/DynamicProperties.java +++ b/src/main/java/eu/dissco/core/translator/terms/specimen/DynamicProperties.java @@ -5,6 +5,7 @@ import java.util.List; public class DynamicProperties extends Term { + public static final String TERM = DWC_PREFIX + "dynamicProperties"; private final List dwcaTerms = List.of(TERM); diff --git a/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismID.java b/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismID.java index ac85beb..f4e624e 100644 --- a/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismID.java +++ b/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismID.java @@ -5,6 +5,7 @@ import java.util.List; public class OrganismID extends Term { + public static final String TERM = DWC_PREFIX + "organismID"; private final List dwcaTerms = List.of(TERM); diff --git a/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismName.java b/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismName.java index 848719d..9f0e6fb 100644 --- a/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismName.java +++ b/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismName.java @@ -5,6 +5,7 @@ import java.util.List; public class OrganismName extends Term { + public static final String TERM = DWC_PREFIX + "organismName"; private final List dwcaTerms = List.of(TERM); diff --git a/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismRemarks.java b/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismRemarks.java index d743a99..7ba3f62 100644 --- a/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismRemarks.java +++ b/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismRemarks.java @@ -5,6 +5,7 @@ import java.util.List; public class OrganismRemarks extends Term { + public static final String TERM = DWC_PREFIX + "organismRemarks"; private final List dwcaTerms = List.of(TERM); diff --git a/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismScope.java b/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismScope.java index 06eeadf..85d5b7d 100644 --- a/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismScope.java +++ b/src/main/java/eu/dissco/core/translator/terms/specimen/OrganismScope.java @@ -5,6 +5,7 @@ import java.util.List; public class OrganismScope extends Term { + public static final String TERM = DWC_PREFIX + "organismScope"; private final List dwcaTerms = List.of(TERM); diff --git a/src/main/java/eu/dissco/core/translator/terms/specimen/SpecimenName.java b/src/main/java/eu/dissco/core/translator/terms/specimen/SpecimenName.java index 4f70550..d00933f 100644 --- a/src/main/java/eu/dissco/core/translator/terms/specimen/SpecimenName.java +++ b/src/main/java/eu/dissco/core/translator/terms/specimen/SpecimenName.java @@ -9,7 +9,8 @@ public class SpecimenName extends Term { public String calculate(DigitalSpecimen ds) { var acceptedIdentification = retrieveAcceptedIdentification(ds); - if (acceptedIdentification != null && acceptedIdentification.getOdsHasTaxonIdentifications() != null + if (acceptedIdentification != null + && acceptedIdentification.getOdsHasTaxonIdentifications() != null && !acceptedIdentification.getOdsHasTaxonIdentifications().isEmpty()) { if (acceptedIdentification.getOdsHasTaxonIdentifications().get(0) .getDwcScientificName() != null) { diff --git a/src/main/java/eu/dissco/core/translator/terms/specimen/TopicDiscipline.java b/src/main/java/eu/dissco/core/translator/terms/specimen/TopicDiscipline.java index 37b8846..cc3673c 100644 --- a/src/main/java/eu/dissco/core/translator/terms/specimen/TopicDiscipline.java +++ b/src/main/java/eu/dissco/core/translator/terms/specimen/TopicDiscipline.java @@ -19,7 +19,8 @@ public class TopicDiscipline extends Term { public OdsTopicDiscipline calculate(DigitalSpecimen ds) { var basisOfRecord = ds.getDwcBasisOfRecord(); var acceptedIdentification = retrieveAcceptedIdentification(ds); - if (acceptedIdentification != null && acceptedIdentification.getOdsHasTaxonIdentifications() != null + if (acceptedIdentification != null + && acceptedIdentification.getOdsHasTaxonIdentifications() != null && !acceptedIdentification.getOdsHasTaxonIdentifications().isEmpty()) { return getDiscipline(basisOfRecord, acceptedIdentification.getOdsHasTaxonIdentifications().get(0).getDwcKingdom()); diff --git a/src/main/java/eu/dissco/core/translator/terms/utils/AgentsUtils.java b/src/main/java/eu/dissco/core/translator/terms/utils/AgentsUtils.java index 7fe17c4..44b6081 100644 --- a/src/main/java/eu/dissco/core/translator/terms/utils/AgentsUtils.java +++ b/src/main/java/eu/dissco/core/translator/terms/utils/AgentsUtils.java @@ -65,10 +65,11 @@ private static void handleMultipleAgents( List agents, String agentValue, String agentId, AgentRoleType role, Type type) { var ids = new String[0]; var agentValues = new String[0]; - if (agentValue != null && (agentValue.contains("&") || agentValue.contains("|"))) { - agentValues = Arrays.stream(agentValue.split("[&|]")).map(String::trim).toArray(String[]::new); + if (needsParsing(agentValue)) { + agentValues = Arrays.stream(agentValue.split("[&|]")).map(String::trim) + .toArray(String[]::new); } - if (agentId != null && (agentId.contains("&") || agentId.contains("|"))) { + if (needsParsing(agentId)) { ids = Arrays.stream(agentId.split("[&|]")).map(String::trim).toArray(String[]::new); } if (agentValues.length == ids.length) { @@ -76,19 +77,27 @@ private static void handleMultipleAgents( constructAgent(agents, agentValues[i], ids[i], role, type); } } else if (agentValues.length > ids.length) { - log.warn( - "The number of agentValues values is greater than ids, ignoring ids for term: {} and agentId: {}", - agentValue, agentId); + if (ids.length != 0) { + log.warn( + "The number of agentValues values is greater than ids, ignoring ids for term: {} and agentId: {}", + agentValue, agentId); + } for (String agent : agentValues) { constructAgent(agents, agent, null, role, type); } } else { - log.warn( - "The number of ids is greater than agentValue, ignoring agentValue values for term: {} and agentId: {}", - agentValue, agentId); + if (agentValues.length != 0) { + log.warn( + "The number of ids is greater than agentValue, ignoring agentValue values for term: {} and agentId: {}", + agentValue, agentId); + } for (String idValue : ids) { constructAgent(agents, null, idValue, role, type); } } } + + private static boolean needsParsing(String value) { + return value != null && (value.contains("&") || value.contains("|")); + } } diff --git a/src/main/java/eu/dissco/core/translator/terms/utils/EntityRelationshipUtils.java b/src/main/java/eu/dissco/core/translator/terms/utils/EntityRelationshipUtils.java new file mode 100644 index 0000000..0cb5d9a --- /dev/null +++ b/src/main/java/eu/dissco/core/translator/terms/utils/EntityRelationshipUtils.java @@ -0,0 +1,47 @@ +package eu.dissco.core.translator.terms.utils; + +import static eu.dissco.core.translator.domain.AgentRoleType.DATA_TRANSLATOR; +import static eu.dissco.core.translator.schema.Agent.Type.SCHEMA_SOFTWARE_APPLICATION; +import static eu.dissco.core.translator.terms.utils.AgentsUtils.addAgent; + +import eu.dissco.core.translator.domain.RelationshipType; +import eu.dissco.core.translator.schema.EntityRelationship; +import java.net.URI; +import java.net.URISyntaxException; +import java.time.Instant; +import java.util.Date; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EntityRelationshipUtils { + + private EntityRelationshipUtils() { + // This is a Utility class + } + + public static EntityRelationship addEntityRelationship( + RelationshipType relationshipType, String relatedResource, String agentName, String agentId) { + if (relatedResource == null) { + log.warn("Related resource for type {} is null. Skipping entity relationship creation.", + relationshipType.getName()); + return null; + } + var entityRelationship = new EntityRelationship() + .withType("ods:EntityRelationship") + .withDwcRelationshipOfResource(relationshipType.getName()) + .withDwcRelatedResourceID(relatedResource) + .withDwcRelationshipEstablishedDate(Date.from(Instant.now())); + entityRelationship.setOdsHasAgents( + addAgent(entityRelationship.getOdsHasAgents(), agentName, agentId, DATA_TRANSLATOR, + SCHEMA_SOFTWARE_APPLICATION)); + if (relatedResource.startsWith("http")) { + try { + entityRelationship.setOdsRelatedResourceURI(new URI(relatedResource)); + } catch (URISyntaxException e) { + log.warn("Could not create URI for related resource: " + relatedResource); + } + } + return entityRelationship; + } + +} \ No newline at end of file diff --git a/src/test/java/eu/dissco/core/translator/component/OrganisationNameComponentTest.java b/src/test/java/eu/dissco/core/translator/component/OrganisationNameComponentTest.java index 640892b..eb66271 100644 --- a/src/test/java/eu/dissco/core/translator/component/OrganisationNameComponentTest.java +++ b/src/test/java/eu/dissco/core/translator/component/OrganisationNameComponentTest.java @@ -50,12 +50,30 @@ class OrganisationNameComponentTest { private CompletableFuture jsonFuture; private OrganisationNameComponent rorComponent; + private static Stream badRorResponse() throws JsonProcessingException { + return Stream.of( + Arguments.of( + MAPPER.readTree(""" + { + "names":"De MuseumFabriek" + } + """) + ), + Arguments.of( + MAPPER.readTree(""" + { + "names": ["De MuseumFabriek"] + } + """) + ) + ); + } + @BeforeEach void setup() { this.rorComponent = new OrganisationNameComponent(client); } - @Test void testGetRorId() throws Exception { // Given @@ -98,7 +116,7 @@ void testGetRorIdFirst() throws Exception { @ParameterizedTest @MethodSource("badRorResponse") - void testBadRorResponse(JsonNode rorResponse) throws Exception { + void testBadRorResponse(JsonNode rorResponse) throws Exception { // Given givenWebclient(); given(jsonFuture.get()).willReturn(rorResponse); @@ -108,25 +126,6 @@ void testBadRorResponse(JsonNode rorResponse) throws Exception { } - private static Stream badRorResponse() throws JsonProcessingException { - return Stream.of( - Arguments.of( - MAPPER.readTree(""" - { - "names":"De MuseumFabriek" - } - """) - ), - Arguments.of( - MAPPER.readTree(""" - { - "names": ["De MuseumFabriek"] - } - """) - ) - ); - } - @Test void testWikidataId() throws Exception { // Given diff --git a/src/test/java/eu/dissco/core/translator/repository/DataMappingRepositoryIT.java b/src/test/java/eu/dissco/core/translator/repository/DataMappingRepositoryIT.java index fad898a..eeb11dc 100644 --- a/src/test/java/eu/dissco/core/translator/repository/DataMappingRepositoryIT.java +++ b/src/test/java/eu/dissco/core/translator/repository/DataMappingRepositoryIT.java @@ -55,7 +55,7 @@ private void givenInsertRecords(String mapping) { .set(DATA_MAPPING.VERSION, 1) .set(DATA_MAPPING.NAME, "Royal Botanic Garden Edinburgh Living Plant Collections Mapping") .set(DATA_MAPPING.CREATOR, "e2befba6-9324-4bb4-9f41-d7dfae4a44b0") - .set(DATA_MAPPING.DATE_CREATED,Instant.parse("2022-09-16T08:25:01.00Z")) + .set(DATA_MAPPING.DATE_CREATED, Instant.parse("2022-09-16T08:25:01.00Z")) .set(DATA_MAPPING.DATE_MODIFIED, Instant.parse("2022-09-16T08:25:01.00Z")) .set(DATA_MAPPING.MAPPING_DATA_STANDARD, "dwc") .set(DATA_MAPPING.DATA, JSONB.valueOf(mapping)) diff --git a/src/test/java/eu/dissco/core/translator/service/BioCaseServiceTest.java b/src/test/java/eu/dissco/core/translator/service/BioCaseServiceTest.java index 7b92ed5..f01c85c 100644 --- a/src/test/java/eu/dissco/core/translator/service/BioCaseServiceTest.java +++ b/src/test/java/eu/dissco/core/translator/service/BioCaseServiceTest.java @@ -49,9 +49,9 @@ class BioCaseServiceTest { private final XMLInputFactory factory = XMLInputFactory.newFactory(); private final ObjectMapper mapper = new ObjectMapper().findAndRegisterModules(); + private final ApplicationProperties properties = new ApplicationProperties(); @Mock private WebClient webClient; - private final ApplicationProperties properties = new ApplicationProperties(); @Mock private SourceSystemComponent sourceSystemComponent; @Mock @@ -75,7 +75,8 @@ void setup() throws IOException { var configuration = new Configuration(Configuration.VERSION_2_3_31); configuration.setTemplateLoader( new FileTemplateLoader(new ClassPathResource("templates").getFile())); - service = new BioCaseService(mapper, properties, webClient, sourceSystemComponent, configuration, factory, + service = new BioCaseService(mapper, properties, webClient, sourceSystemComponent, + configuration, factory, kafkaService, enrichmentProperties, digitalSpecimenDirector, fdoProperties); // Given diff --git a/src/test/java/eu/dissco/core/translator/service/DwcaServiceTest.java b/src/test/java/eu/dissco/core/translator/service/DwcaServiceTest.java index 7e9983e..1ef79ea 100644 --- a/src/test/java/eu/dissco/core/translator/service/DwcaServiceTest.java +++ b/src/test/java/eu/dissco/core/translator/service/DwcaServiceTest.java @@ -64,6 +64,7 @@ class DwcaServiceTest { private final XMLInputFactory factory = XMLInputFactory.newFactory(); + private final ApplicationProperties applicationProperties = new ApplicationProperties(); @Mock private WebClient webClient; @Mock @@ -86,9 +87,6 @@ class DwcaServiceTest { private BaseDigitalObjectDirector digitalSpecimenDirector; @Mock private FdoProperties fdoProperties; - private final ApplicationProperties applicationProperties = new ApplicationProperties(); - - private DwcaService service; private static void cleanup(String first) throws IOException { diff --git a/src/test/java/eu/dissco/core/translator/terms/BiocaseDigitalObjectDirectorTest.java b/src/test/java/eu/dissco/core/translator/terms/BiocaseDigitalObjectDirectorTest.java index e04fc0b..ae2b8cb 100644 --- a/src/test/java/eu/dissco/core/translator/terms/BiocaseDigitalObjectDirectorTest.java +++ b/src/test/java/eu/dissco/core/translator/terms/BiocaseDigitalObjectDirectorTest.java @@ -111,6 +111,8 @@ void testConstructAbcdDigitalSpecimen(ObjectNode identifications, int totalIdent .willReturn("https://www.wikidata.org/wiki/Q604487"); given(termMapper.retrieveTerm(any(PhysicalSpecimenIDType.class), eq(specimenJson), eq(false))) .willReturn(OdsPhysicalSpecimenIDType.RESOLVABLE.value()); + given(fdoProperties.getDigitalSpecimenType()).willReturn( + "https://hdl.handle.net/21.T11148/ce794a6f4df42eb7e77e"); // When var result = director.assembleDigitalSpecimenTerm(specimenJson, false); @@ -118,10 +120,13 @@ void testConstructAbcdDigitalSpecimen(ObjectNode identifications, int totalIdent // Then assertThat(result).isNotNull(); assertThat(result.getOdsStatus()).isEqualTo(OdsStatus.ACTIVE); - assertThat(result.getOdsHasEntityRelationships()).asInstanceOf(InstanceOfAssertFactories.LIST).hasSize(4); - assertThat(result.getOdsHasIdentifiers()).asInstanceOf(InstanceOfAssertFactories.LIST).hasSize(4); + assertThat(result.getOdsHasEntityRelationships()).asInstanceOf(InstanceOfAssertFactories.LIST) + .hasSize(4); + assertThat(result.getOdsHasIdentifiers()).asInstanceOf(InstanceOfAssertFactories.LIST) + .hasSize(4); assertThat(result.getOdsHasCitations()).asInstanceOf(InstanceOfAssertFactories.LIST).hasSize(1); - assertThat(result.getOdsHasIdentifications()).asInstanceOf(InstanceOfAssertFactories.LIST).hasSize(totalIdentifications); + assertThat(result.getOdsHasIdentifications()).asInstanceOf(InstanceOfAssertFactories.LIST) + .hasSize(totalIdentifications); } @ParameterizedTest diff --git a/src/test/java/eu/dissco/core/translator/terms/DwcaDigitalObjectDirectorTest.java b/src/test/java/eu/dissco/core/translator/terms/DwcaDigitalObjectDirectorTest.java index 3e82c67..8835973 100644 --- a/src/test/java/eu/dissco/core/translator/terms/DwcaDigitalObjectDirectorTest.java +++ b/src/test/java/eu/dissco/core/translator/terms/DwcaDigitalObjectDirectorTest.java @@ -58,6 +58,8 @@ void testConstructDwcaDigitalSpecimen() throws Exception { .willReturn("https://ror.org/0443cwa12"); given(termMapper.retrieveTerm(any(PhysicalSpecimenIDType.class), eq(specimenJson), eq(true))) .willReturn(OdsPhysicalSpecimenIDType.LOCAL.value()); + given(fdoProperties.getDigitalSpecimenType()).willReturn( + "https://hdl.handle.net/21.T11148/ce794a6f4df42eb7e77e"); // When var result = director.assembleDigitalSpecimenTerm(specimenJson, true); @@ -65,10 +67,13 @@ void testConstructDwcaDigitalSpecimen() throws Exception { // Then assertThat(result).isNotNull(); assertThat(result.getOdsStatus()).isEqualTo(OdsStatus.ACTIVE); - assertThat(result.getOdsHasEntityRelationships()).asInstanceOf(InstanceOfAssertFactories.LIST).hasSize(3); - assertThat(result.getOdsHasIdentifiers()).asInstanceOf(InstanceOfAssertFactories.LIST).hasSize(3); + assertThat(result.getOdsHasEntityRelationships()).asInstanceOf(InstanceOfAssertFactories.LIST) + .hasSize(3); + assertThat(result.getOdsHasIdentifiers()).asInstanceOf(InstanceOfAssertFactories.LIST) + .hasSize(3); assertThat(result.getOdsHasCitations()).asInstanceOf(InstanceOfAssertFactories.LIST).hasSize(2); - assertThat(result.getOdsHasIdentifications()).asInstanceOf(InstanceOfAssertFactories.LIST).hasSize(2); + assertThat(result.getOdsHasIdentifications()).asInstanceOf(InstanceOfAssertFactories.LIST) + .hasSize(2); } @Test @@ -83,16 +88,21 @@ void testConstructDwcaDigitalSpecimenSingleIdentification() throws Exception { .willReturn("https://ror.org/0443cwa12"); given(termMapper.retrieveTerm(any(PhysicalSpecimenIDType.class), eq(specimenJson), eq(true))) .willReturn(OdsPhysicalSpecimenIDType.LOCAL.value()); + given(fdoProperties.getDigitalSpecimenType()).willReturn( + "https://hdl.handle.net/21.T11148/ce794a6f4df42eb7e77e"); // When var result = director.assembleDigitalSpecimenTerm(specimenJson, true); // Then assertThat(result).isNotNull(); - assertThat(result.getOdsHasEntityRelationships()).asInstanceOf(InstanceOfAssertFactories.LIST).hasSize(3); - assertThat(result.getOdsHasIdentifiers()).asInstanceOf(InstanceOfAssertFactories.LIST).hasSize(3); + assertThat(result.getOdsHasEntityRelationships()).asInstanceOf(InstanceOfAssertFactories.LIST) + .hasSize(3); + assertThat(result.getOdsHasIdentifiers()).asInstanceOf(InstanceOfAssertFactories.LIST) + .hasSize(3); assertThat(result.getOdsHasCitations()).asInstanceOf(InstanceOfAssertFactories.LIST).hasSize(1); - assertThat(result.getOdsHasIdentifications()).asInstanceOf(InstanceOfAssertFactories.LIST).hasSize(1); + assertThat(result.getOdsHasIdentifications()).asInstanceOf(InstanceOfAssertFactories.LIST) + .hasSize(1); assertThat(((eu.dissco.core.translator.schema.Identification) result.getOdsHasIdentifications() .get(0)).getOdsIsVerifiedIdentification()).isTrue(); } @@ -106,6 +116,8 @@ void testConstructDwcaDigitalMedia() throws JsonProcessingException, Organisatio "National Museum of Natural History"); given(termMapper.retrieveTerm(any(Term.class), eq(specimenJson), eq(true))).willReturn( "a mapped term"); + given(fdoProperties.getDigitalMediaType()).willReturn( + "https://hdl.handle.net/21.T11148/ce794a6f4df42eb7e77e"); // When var result = director.assembleDigitalMedia(true, specimenJson, @@ -113,8 +125,10 @@ void testConstructDwcaDigitalMedia() throws JsonProcessingException, Organisatio // Then assertThat(result).isNotNull(); - assertThat(result.getOdsHasEntityRelationships()).asInstanceOf(InstanceOfAssertFactories.LIST).hasSize(3); - assertThat(result.getOdsHasIdentifiers()).asInstanceOf(InstanceOfAssertFactories.LIST).hasSize(2); + assertThat(result.getOdsHasEntityRelationships()).asInstanceOf(InstanceOfAssertFactories.LIST) + .hasSize(3); + assertThat(result.getOdsHasIdentifiers()).asInstanceOf(InstanceOfAssertFactories.LIST) + .hasSize(2); } private JsonNode givenDwcaMediaObject() throws JsonProcessingException { diff --git a/src/test/java/eu/dissco/core/translator/terms/media/MediaTypeTest.java b/src/test/java/eu/dissco/core/translator/terms/media/MediaTypeTest.java index d129444..18824e7 100644 --- a/src/test/java/eu/dissco/core/translator/terms/media/MediaTypeTest.java +++ b/src/test/java/eu/dissco/core/translator/terms/media/MediaTypeTest.java @@ -40,6 +40,7 @@ private static Stream provideFormatTypes() { private static Stream provideABCDFormats() { return Stream.of( Arguments.of("image/jpeg", "Still_Image"), + Arguments.of("APPLICATION/JSON", "Interactive_Resource"), Arguments.of("unknown/format", null), Arguments.of(null, null) ); diff --git a/src/test/java/eu/dissco/core/translator/terms/utils/EntityRelationshipUtilsTest.java b/src/test/java/eu/dissco/core/translator/terms/utils/EntityRelationshipUtilsTest.java new file mode 100644 index 0000000..c5a2c59 --- /dev/null +++ b/src/test/java/eu/dissco/core/translator/terms/utils/EntityRelationshipUtilsTest.java @@ -0,0 +1,81 @@ +package eu.dissco.core.translator.terms.utils; + +import static eu.dissco.core.translator.domain.AgentRoleType.DATA_TRANSLATOR; +import static eu.dissco.core.translator.domain.RelationshipType.HAS_FDO_TYPE; +import static eu.dissco.core.translator.domain.RelationshipType.HAS_ORGANISATION_ID; +import static eu.dissco.core.translator.schema.Agent.Type.SCHEMA_SOFTWARE_APPLICATION; +import static eu.dissco.core.translator.terms.utils.AgentsUtils.addAgent; +import static org.assertj.core.api.Assertions.assertThat; + +import eu.dissco.core.translator.domain.RelationshipType; +import eu.dissco.core.translator.schema.EntityRelationship; +import java.net.URI; +import java.net.URISyntaxException; +import java.time.Instant; +import java.util.Date; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class EntityRelationshipUtilsTest { + + public static final String APP_NAME = "DiSSCo Translator Service"; + public static final String APP_PID = "https://hdl.handle.net/TEST/XXX-XXX-XXX"; + + public static Stream erProvider() throws URISyntaxException { + return Stream.of( + Arguments.of(HAS_ORGANISATION_ID, "https://ror.org/0566bfb96", + new URI("https://ror.org/0566bfb96") + ), + Arguments.of(HAS_ORGANISATION_ID, "0566bfb96", null + ), + Arguments.of(HAS_ORGANISATION_ID, "https://ror.org/05^^@^#^66bfb96", null + ) + ); + } + + @ParameterizedTest + @MethodSource("erProvider") + void testAddEntityRelationship(RelationshipType relationshipType, String relatedResource, + URI relatedResourceURI) { + // Given + var expected = createEntityRelationship(relationshipType, relatedResource, relatedResourceURI); + + // When + var result = EntityRelationshipUtils.addEntityRelationship(relationshipType, relatedResource, + APP_NAME, APP_PID); + + // Then + assertThat(result).usingRecursiveComparison().ignoringFields("dwcRelationshipEstablishedDate") + .isEqualTo(expected); + } + + @Test + void testNullRelatedResource() { + // When + var result = EntityRelationshipUtils.addEntityRelationship(HAS_FDO_TYPE, null, APP_NAME, + APP_PID); + + // Then + assertThat(result).isNull(); + } + + private EntityRelationship createEntityRelationship(RelationshipType relationshipType, + String relatedResource, URI relatedResourceURI) { + return new EntityRelationship() + .withType("ods:EntityRelationship") + .withDwcRelationshipOfResource(relationshipType.getName()) + .withDwcRelatedResourceID(relatedResource) + .withOdsRelatedResourceURI(relatedResourceURI) + .withDwcRelationshipEstablishedDate(Date.from(Instant.now())) + .withOdsHasAgents(addAgent(List.of(), APP_NAME, APP_PID, + DATA_TRANSLATOR, SCHEMA_SOFTWARE_APPLICATION)); + + } +}