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