diff --git a/pom.xml b/pom.xml index fcacc70a4..8b703505f 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 2.2.8.RELEASE - 1.12.9 + 1.12.10 0.59 1.3 1.25 diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/LookupServiceIT.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/LookupServiceIT.java index 0b08ec55b..ea556562f 100644 --- a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/LookupServiceIT.java +++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/LookupServiceIT.java @@ -451,7 +451,6 @@ public void explicitMappingsTest() { params.setDatasetKey(d1.getKey()); params.setInstitutionCode(i1.getCode()); params.setCollectionCode(c5.getCode()); - params.setDatasetKey(d1.getKey()); // When LookupResult result = lookupService.lookup(params); @@ -536,7 +535,6 @@ public void ambiguousExplicitMappingsTest() { params.setInstitutionId(occMappingI22.getIdentifier()); params.setCollectionCode(occMappingC2.getCode()); params.setCollectionId(occMappingC22.getIdentifier()); - params.setDatasetKey(d1.getKey()); // When LookupResult result = lookupService.lookup(params); @@ -553,6 +551,39 @@ public void ambiguousExplicitMappingsTest() { assertEquals(Match.Status.AMBIGUOUS_EXPLICIT_MAPPINGS, collectionMatch.getStatus()); } + @Test + public void explicitMappingsWithParentCodeTest() { + // State + Dataset d1 = createDataset(); + + OccurrenceMapping occMappingC1 = new OccurrenceMapping(); + occMappingC1.setDatasetKey(d1.getKey()); + occMappingC1.setParentCode(i1.getCode()); + collectionService.addOccurrenceMapping(c1.getKey(), occMappingC1); + + LookupParams params = new LookupParams(); + params.setDatasetKey(d1.getKey()); + params.setInstitutionCode(i1.getCode()); + params.setInstitutionId(i1.getKey().toString()); + + // When + LookupResult result = lookupService.lookup(params); + + // Should + assertNotNull(result.getInstitutionMatch()); + Match institutionMatch = result.getInstitutionMatch(); + assertEquals(Match.MatchType.EXACT, institutionMatch.getMatchType()); + assertEquals(i1.getKey(), institutionMatch.getEntityMatched().getKey()); + assertEquals(2, institutionMatch.getReasons().size()); + assertEquals(Match.Status.ACCEPTED, institutionMatch.getStatus()); + + assertNotNull(result.getCollectionMatch()); + Match collectionMatch = result.getCollectionMatch(); + assertEquals(Match.MatchType.EXPLICIT_MAPPING, collectionMatch.getMatchType()); + assertEquals(c1.getKey(), collectionMatch.getEntityMatched().getKey()); + assertEquals(Match.Status.ACCEPTED, collectionMatch.getStatus()); + } + @Test public void countryMatchTest() { // State diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/LookupMapper.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/LookupMapper.java index 9685263b5..277e5cc63 100644 --- a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/LookupMapper.java +++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/LookupMapper.java @@ -26,6 +26,7 @@ public interface LookupMapper { List lookup( @Nullable @Param("code") String code, + @Nullable @Param("parentCode") String parentCode, @Nullable @Param("identifier") String identifier, @Nullable @Param("key") UUID key, @Nullable @Param("datasetKey") UUID datasetKey); diff --git a/registry-persistence/src/main/resources/liquibase/129-parent-code-occurrence-mapping.xml b/registry-persistence/src/main/resources/liquibase/129-parent-code-occurrence-mapping.xml new file mode 100644 index 000000000..4a867216e --- /dev/null +++ b/registry-persistence/src/main/resources/liquibase/129-parent-code-occurrence-mapping.xml @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/registry-persistence/src/main/resources/liquibase/master.xml b/registry-persistence/src/main/resources/liquibase/master.xml index 970501159..f76297667 100644 --- a/registry-persistence/src/main/resources/liquibase/master.xml +++ b/registry-persistence/src/main/resources/liquibase/master.xml @@ -134,4 +134,5 @@ + diff --git a/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/CollectionMapper.xml b/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/CollectionMapper.xml index 4addff30d..ccdaf99c1 100644 --- a/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/CollectionMapper.xml +++ b/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/CollectionMapper.xml @@ -523,6 +523,7 @@ INNER JOIN occurrence_mapping om ON om.key = com.occurrence_mapping_key WHERE c.deleted is null AND om.dataset_key = #{datasetKey,jdbcType=OTHER} AND (om.code IS NULL OR om.code = #{code,jdbcType=VARCHAR}) + AND (om.parent_code IS NULL OR om.parent_code = #{parentCode,jdbcType=VARCHAR}) AND (om.identifier IS NULL OR om.identifier = #{identifier,jdbcType=VARCHAR}) ) AS matches diff --git a/registry-service/README.md b/registry-service/README.md index 039e05e98..38090b29c 100644 --- a/registry-service/README.md +++ b/registry-service/README.md @@ -39,6 +39,7 @@ when there are more than 1 possible combination within a dataset. This allows us - All the occurrences from the dataset X have to be mapped to the institution I - All the occurrences from the dataset X and code Y have to be mapped to the institution I - All the occurrences from the dataset X, code Y and identifier Z have to be mapped to the institution I +- For collections only, all the occurrences from the dataset X and parentCode Y(this is the institution code) have to be mapped to the collection C There can be as many combinations as needed. diff --git a/registry-service/src/main/java/org/gbif/registry/service/collections/lookup/matchers/BaseMatcher.java b/registry-service/src/main/java/org/gbif/registry/service/collections/lookup/matchers/BaseMatcher.java index 03c1cfb56..50f55e7cd 100644 --- a/registry-service/src/main/java/org/gbif/registry/service/collections/lookup/matchers/BaseMatcher.java +++ b/registry-service/src/main/java/org/gbif/registry/service/collections/lookup/matchers/BaseMatcher.java @@ -203,17 +203,18 @@ private static String cleanString(String value) { return !Strings.isNullOrEmpty(value) ? value.trim() : null; } - protected List getDbMatches(String codeParam, String identifierParam, UUID datasetKey) { + protected List getDbMatches(String codeParam, String parentCodeParam, String identifierParam, UUID datasetKey) { String code = cleanString(codeParam); + String parentCode = cleanString(parentCodeParam); String identifier = cleanString(identifierParam); - if (code == null && identifier == null) { + if (code == null && identifier == null && datasetKey == null) { return Collections.emptyList(); } UUID key = parseUUID(identifier); - return getLookupMapper().lookup(code, identifier, key, datasetKey); + return getLookupMapper().lookup(code, parentCode, identifier, key, datasetKey); } protected Match createMatch( diff --git a/registry-service/src/main/java/org/gbif/registry/service/collections/lookup/matchers/CollectionMatcher.java b/registry-service/src/main/java/org/gbif/registry/service/collections/lookup/matchers/CollectionMatcher.java index f8158edae..168dcd76b 100644 --- a/registry-service/src/main/java/org/gbif/registry/service/collections/lookup/matchers/CollectionMatcher.java +++ b/registry-service/src/main/java/org/gbif/registry/service/collections/lookup/matchers/CollectionMatcher.java @@ -21,19 +21,13 @@ import org.gbif.registry.persistence.mapper.collections.LookupMapper; import org.gbif.registry.persistence.mapper.collections.dto.CollectionMatchedDto; import org.gbif.registry.service.collections.lookup.Matches; - -import java.net.URI; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import java.net.URI; +import java.util.*; + import static org.gbif.api.model.collections.lookup.Match.Reason.INST_COLL_MISMATCH; @Component @@ -53,7 +47,11 @@ public Matches matchCollections( Matches matches = new Matches<>(); List dbMatches = - getDbMatches(params.getCollectionCode(), params.getCollectionId(), params.getDatasetKey()); + getDbMatches( + params.getCollectionCode(), + params.getInstitutionCode(), + params.getCollectionId(), + params.getDatasetKey()); // the queries may return duplicates because a collection can match with several fields Map dtosMap = new HashMap<>(); @@ -110,10 +108,19 @@ protected Match createCollectionMatch( if (institutionMatched.getEntityMatched().getKey().equals(dto.getInstitutionKey()) && institutionMatched.getMatchType() == Match.MatchType.EXACT || institutionMatched.getMatchType() == Match.MatchType.EXPLICIT_MAPPING) { - Match match = Match.exact(toEntityMatched(dto), getMatchReasons(dto)); - match.addReason(Match.Reason.BELONGS_TO_INSTITUTION_MATCHED); - exactMatches.add(match); - return match; + + if (dto.isExplicitMapping()) { + Match match = + Match.explicitMapping(toEntityMatched(dto), getMatchReasons(dto)); + match.addReason(Match.Reason.BELONGS_TO_INSTITUTION_MATCHED); + explicitMatches.add(match); + return match; + } else { + Match match = Match.exact(toEntityMatched(dto), getMatchReasons(dto)); + match.addReason(Match.Reason.BELONGS_TO_INSTITUTION_MATCHED); + exactMatches.add(match); + return match; + } } } diff --git a/registry-service/src/main/java/org/gbif/registry/service/collections/lookup/matchers/InstitutionMatcher.java b/registry-service/src/main/java/org/gbif/registry/service/collections/lookup/matchers/InstitutionMatcher.java index 6b134b416..79cf89c76 100644 --- a/registry-service/src/main/java/org/gbif/registry/service/collections/lookup/matchers/InstitutionMatcher.java +++ b/registry-service/src/main/java/org/gbif/registry/service/collections/lookup/matchers/InstitutionMatcher.java @@ -58,7 +58,7 @@ public Matches matchInstitutions(LookupParams params) { List dbMatches = getDbMatches( - params.getInstitutionCode(), params.getInstitutionId(), params.getDatasetKey()); + params.getInstitutionCode(), null, params.getInstitutionId(), params.getDatasetKey()); // the queries may return duplicates because we retrieve the list of identifiers in the same // query. Also, if an institution matches with several fields it will be duplicated