diff --git a/pom.xml b/pom.xml
index 25e60477c8..6530c95f5f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -84,21 +84,21 @@
2.2.8.RELEASE
- 1.16.5
+ 1.16.7
0.59
- 1.3
+ 1.4
1.26
1.13
2.17
1.51.0
0.10
2.2
- 0.60
+ 0.67
1.8.0
4.1.0-gbif-4
0.195.1
1.0.5
- 2.125
+ 2.128
3.2
diff --git a/registry-events/src/main/java/org/gbif/registry/events/collections/SubEntityCollectionEvent.java b/registry-events/src/main/java/org/gbif/registry/events/collections/SubEntityCollectionEvent.java
index c29bcfb116..114652320f 100644
--- a/registry-events/src/main/java/org/gbif/registry/events/collections/SubEntityCollectionEvent.java
+++ b/registry-events/src/main/java/org/gbif/registry/events/collections/SubEntityCollectionEvent.java
@@ -13,11 +13,9 @@
*/
package org.gbif.registry.events.collections;
-import org.gbif.api.model.collections.CollectionEntity;
-
-import java.util.UUID;
-
import com.google.common.base.Preconditions;
+import java.util.UUID;
+import org.gbif.api.model.collections.CollectionEntity;
/**
* This event is fired after collection entity components such as contacts, identifiers or tags have
@@ -66,6 +64,22 @@ public static SubEntityCollectionEvent new
eventType);
}
+ public static SubEntityCollectionEvent newInstance(
+ UUID collectionEntityKey,
+ Class collectionEntityClass,
+ Class subEntity,
+ long subEntityKey,
+ EventType eventType) {
+ return new SubEntityCollectionEvent<>(
+ collectionEntityKey,
+ collectionEntityClass,
+ subEntity,
+ null,
+ null,
+ String.valueOf(subEntityKey),
+ eventType);
+ }
+
public static SubEntityCollectionEvent newInstance(
UUID collectionEntityKey,
Class collectionEntityClass,
diff --git a/registry-integration-tests/pom.xml b/registry-integration-tests/pom.xml
index 06e246132d..3abaedee5b 100644
--- a/registry-integration-tests/pom.xml
+++ b/registry-integration-tests/pom.xml
@@ -141,6 +141,13 @@
junit-jupiter-params
test
+
+
+ net.java.dev.jna
+ jna
+ 5.9.0
+ test
+
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/database/BaseDBTest.java b/registry-integration-tests/src/test/java/org/gbif/registry/database/BaseDBTest.java
index 64d4c0af1a..25697e8f95 100644
--- a/registry-integration-tests/src/test/java/org/gbif/registry/database/BaseDBTest.java
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/database/BaseDBTest.java
@@ -13,14 +13,8 @@
*/
package org.gbif.registry.database;
-import org.gbif.registry.ws.it.fixtures.TestConstants;
-
import java.sql.SQLException;
import java.time.Duration;
-
-import org.testcontainers.containers.PostgreSQLContainer;
-import org.testcontainers.containers.wait.strategy.Wait;
-
import liquibase.Contexts;
import liquibase.Liquibase;
import liquibase.database.Database;
@@ -28,6 +22,9 @@
import liquibase.database.jvm.JdbcConnection;
import liquibase.exception.LiquibaseException;
import liquibase.resource.ClassLoaderResourceAccessor;
+import org.gbif.registry.ws.it.fixtures.TestConstants;
+import org.testcontainers.containers.PostgreSQLContainer;
+import org.testcontainers.containers.wait.strategy.Wait;
public class BaseDBTest {
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/database/TestCaseDatabaseInitializer.java b/registry-integration-tests/src/test/java/org/gbif/registry/database/TestCaseDatabaseInitializer.java
index f766eaa779..bc9fc4775f 100644
--- a/registry-integration-tests/src/test/java/org/gbif/registry/database/TestCaseDatabaseInitializer.java
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/database/TestCaseDatabaseInitializer.java
@@ -13,23 +13,20 @@
*/
package org.gbif.registry.database;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.sql.DataSource;
-
+import com.google.common.base.Throwables;
+import lombok.Data;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.context.junit.jupiter.SpringExtension;
-import com.google.common.base.Throwables;
-
-import lombok.Data;
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
/**
* A Rule that will truncate the tables ready for a new test. It is expected to do this before each
@@ -106,7 +103,10 @@ public class TestCaseDatabaseInitializer implements BeforeEachCallback {
"collection_contact",
"institution_collection_contact",
"collection_collection_contact",
- "collections_batch");
+ "collections_batch",
+ "collection_descriptor_group",
+ "collection_descriptor",
+ "collection_descriptor_verbatim");
public TestCaseDatabaseInitializer() {}
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/test/mocks/NubResourceClientMock.java b/registry-integration-tests/src/test/java/org/gbif/registry/test/mocks/NubResourceClientMock.java
new file mode 100644
index 0000000000..709055054a
--- /dev/null
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/test/mocks/NubResourceClientMock.java
@@ -0,0 +1,70 @@
+package org.gbif.registry.test.mocks;
+
+import java.util.Arrays;
+import org.gbif.api.model.checklistbank.NameUsageMatch;
+import org.gbif.api.model.common.LinneanClassification;
+import org.gbif.api.v2.NameUsageMatch2;
+import org.gbif.api.v2.RankedName;
+import org.gbif.api.vocabulary.Rank;
+import org.gbif.checklistbank.ws.client.NubResourceClient;
+
+public class NubResourceClientMock implements NubResourceClient {
+
+ public static final RankedName DEFAULT_USAGE = new RankedName(100, "usage", Rank.SPECIES);
+ public static final RankedName DEFAULT_HIGHEST_USAGE =
+ new RankedName(1, "superHigherUsage", Rank.KINGDOM);
+
+ @Override
+ public NameUsageMatch match(
+ String s,
+ String s1,
+ String s2,
+ String s3,
+ String s4,
+ String s5,
+ String s6,
+ String s7,
+ LinneanClassification linneanClassification,
+ Boolean aBoolean,
+ Boolean aBoolean1) {
+ return null;
+ }
+
+ @Override
+ public NameUsageMatch2 match2(
+ String scientificName2,
+ String scientificName,
+ String authorship2,
+ String authorship,
+ String rank2,
+ String rank,
+ String genericName,
+ String specificEpithet,
+ String infraspecificEpithet,
+ LinneanClassification classification,
+ Boolean strict,
+ Boolean verbose) {
+
+ if ("Aves".equalsIgnoreCase(scientificName)) {
+ NameUsageMatch2 nameUsageMatch2 = new NameUsageMatch2();
+ nameUsageMatch2.setUsage(new RankedName(212, "Aves", Rank.CLASS));
+ nameUsageMatch2.setClassification(
+ Arrays.asList(
+ new RankedName(1, "Animalia", Rank.KINGDOM),
+ new RankedName(44, "Chordata", Rank.PHYLUM),
+ new RankedName(212, "Aves", Rank.CLASS)));
+ NameUsageMatch2.Diagnostics diagnostics = new NameUsageMatch2.Diagnostics();
+ diagnostics.setMatchType(NameUsageMatch.MatchType.EXACT);
+ nameUsageMatch2.setDiagnostics(diagnostics);
+ return nameUsageMatch2;
+ }
+
+ NameUsageMatch2 nameUsageMatch2 = new NameUsageMatch2();
+ nameUsageMatch2.setUsage(DEFAULT_USAGE);
+
+ nameUsageMatch2.setClassification(
+ Arrays.asList(new RankedName(50, "higherUsage", Rank.GENUS), DEFAULT_HIGHEST_USAGE));
+
+ return nameUsageMatch2;
+ }
+}
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/OrganizationIT.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/OrganizationIT.java
index 56e21b6af2..8f0c0f8a57 100644
--- a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/OrganizationIT.java
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/OrganizationIT.java
@@ -13,6 +13,8 @@
*/
package org.gbif.registry.ws.it;
+import java.math.BigDecimal;
+
import org.gbif.api.model.common.paging.PagingRequest;
import org.gbif.api.model.common.paging.PagingResponse;
import org.gbif.api.model.registry.Dataset;
@@ -44,9 +46,13 @@
import javax.annotation.Nullable;
import org.apache.commons.beanutils.BeanUtils;
+import org.geojson.Feature;
+import org.geojson.FeatureCollection;
+import org.geojson.Point;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
+import org.locationtech.jts.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.server.LocalServerPort;
@@ -266,6 +272,34 @@ public void testList(ServiceType serviceType) {
assertResultsOfSize(service.listDeleted(searchParams), 1);
}
+ @ParameterizedTest
+ @EnumSource(ServiceType.class)
+ public void testListPublishersAsGeoJson(ServiceType serviceType) {
+ OrganizationService service = (OrganizationService) getService(serviceType);
+
+ Node node = testDataFactory.newNode();
+ UUID nodeKey = nodeResource.create(node);
+
+ Organization o1 = testDataFactory.newOrganization(nodeKey);
+ o1.setTitle("n1");
+ o1.setEndorsementApproved(true);
+ o1.setLatitude(BigDecimal.valueOf(50d));
+ o1.setLongitude(BigDecimal.valueOf(12d));
+
+ UUID key1 = getService(serviceType).create(o1);
+
+ FeatureCollection expectedFeatureCollection = new FeatureCollection();
+ Feature f1 = new Feature();
+ f1.setGeometry(new Point(12d, 50d));
+ f1.setProperty("organization", "n1");
+ f1.setProperty("key", key1.toString());
+ expectedFeatureCollection.add(f1);
+
+ OrganizationRequestSearchParams searchParams = new OrganizationRequestSearchParams();
+ FeatureCollection result = service.listGeoJson(searchParams);
+ Assert.equals(expectedFeatureCollection.getFeatures().size(),result.getFeatures().size());
+ }
+
private void createOrgs(UUID nodeKey, ServiceType serviceType, Country... countries) {
OrganizationService service = (OrganizationService) getService(serviceType);
for (Country c : countries) {
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/RegistryIntegrationTestsConfiguration.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/RegistryIntegrationTestsConfiguration.java
index 3b64caeaa8..b03cd0e823 100644
--- a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/RegistryIntegrationTestsConfiguration.java
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/RegistryIntegrationTestsConfiguration.java
@@ -14,12 +14,15 @@
package org.gbif.registry.ws.it;
import com.zaxxer.hikari.HikariDataSource;
+import java.util.Collections;
+import java.util.Date;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.ConvertUtilsBean;
import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.commons.beanutils.converters.DateTimeConverter;
import org.gbif.api.vocabulary.UserRole;
+import org.gbif.checklistbank.ws.client.NubResourceClient;
import org.gbif.registry.doi.config.TitleLookupConfiguration;
import org.gbif.registry.events.config.VarnishPurgeConfiguration;
import org.gbif.registry.mail.EmailSenderImpl;
@@ -29,6 +32,7 @@
import org.gbif.registry.search.dataset.indexing.ws.GbifWsClient;
import org.gbif.registry.surety.OrganizationEmailTemplateManagerIT;
import org.gbif.registry.test.mocks.ConceptClientMock;
+import org.gbif.registry.test.mocks.NubResourceClientMock;
import org.gbif.registry.ws.config.DataSourcesConfiguration;
import org.gbif.vocabulary.client.ConceptClient;
import org.gbif.ws.client.filter.SimplePrincipalProvider;
@@ -56,9 +60,6 @@
import org.springframework.test.context.ActiveProfiles;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
-import java.util.Collections;
-import java.util.Date;
-
@TestConfiguration
@SpringBootApplication(
exclude = {
@@ -212,4 +213,9 @@ public static void main(String[] args) {
public ConceptClient conceptClient() {
return new ConceptClientMock();
}
+
+ @Bean
+ public NubResourceClient nubResourceClient() {
+ return new NubResourceClientMock();
+ }
}
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/BaseCollectionEntityResourceIT.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/BaseCollectionEntityResourceIT.java
index 27e111c908..c7234705e4 100644
--- a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/BaseCollectionEntityResourceIT.java
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/BaseCollectionEntityResourceIT.java
@@ -110,7 +110,7 @@ abstract class BaseCollectionEntityResourceIT<
@Autowired protected ObjectMapper objectMapper;
@Autowired protected MockMvc mockMvc;
- @MockBean private ResourceNotFoundService resourceNotFoundService;
+ @MockBean protected ResourceNotFoundService resourceNotFoundService;
public BaseCollectionEntityResourceIT(
Class extends BaseCollectionEntityClient> cls,
@@ -528,7 +528,7 @@ public void listChangeSuggestionTest() {
UUID entityKey = UUID.randomUUID();
Pageable page = new PagingRequest();
- when(getMockChangeSuggestionService().list(status, type, proposerEmail, entityKey, page))
+ when(getMockChangeSuggestionService().list(status, type, proposerEmail, entityKey, null, page))
.thenReturn(
new PagingResponse<>(
new PagingRequest(), 1L, Collections.singletonList(changeSuggestion)));
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/BaseResourceIT.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/BaseResourceIT.java
index a5339b391e..49422a4f39 100644
--- a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/BaseResourceIT.java
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/BaseResourceIT.java
@@ -13,6 +13,12 @@
*/
package org.gbif.registry.ws.it.collections.resource;
+
+import static org.gbif.registry.ws.it.fixtures.TestConstants.IT_APP_KEY2;
+
+import java.util.Arrays;
+import java.util.Collections;
+import javax.sql.DataSource;
import org.gbif.api.vocabulary.UserRole;
import org.gbif.registry.search.test.EsManageServer;
import org.gbif.registry.test.mocks.IdentityServiceMock;
@@ -26,12 +32,6 @@
import org.gbif.ws.security.GbifAuthenticationManager;
import org.gbif.ws.security.GbifAuthenticationManagerImpl;
import org.gbif.ws.security.KeyStore;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-import javax.sql.DataSource;
-
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
@@ -55,8 +55,6 @@
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.PlatformTransactionManager;
-import static org.gbif.registry.ws.it.fixtures.TestConstants.IT_APP_KEY2;
-
/** Base class for IT tests that initializes data sources and basic security settings. */
@ExtendWith(SpringExtension.class)
@SpringBootTest(
@@ -146,6 +144,7 @@ protected T prepareClient(String username, int localServerPort, Class cls
return clientBuilder
.withUrl("http://localhost:" + localServerPort)
.withCredentials(username, username)
+ .withFormEncoder()
.build(cls);
}
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/CollectionResourceIT.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/CollectionResourceIT.java
index e09190d3fd..7ec8b956f1 100644
--- a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/CollectionResourceIT.java
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/CollectionResourceIT.java
@@ -13,13 +13,32 @@
*/
package org.gbif.registry.ws.it.collections.resource;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import lombok.SneakyThrows;
import org.gbif.api.model.collections.Collection;
import org.gbif.api.model.collections.CollectionImportParams;
+import org.gbif.api.model.collections.descriptors.Descriptor;
+import org.gbif.api.model.collections.descriptors.DescriptorGroup;
import org.gbif.api.model.collections.latimercore.ObjectGroup;
import org.gbif.api.model.collections.request.CollectionSearchRequest;
+import org.gbif.api.model.collections.request.DescriptorGroupSearchRequest;
+import org.gbif.api.model.collections.request.DescriptorSearchRequest;
import org.gbif.api.model.collections.suggestions.CollectionChangeSuggestion;
import org.gbif.api.model.collections.suggestions.Type;
import org.gbif.api.model.collections.view.CollectionView;
+import org.gbif.api.model.common.export.ExportFormat;
import org.gbif.api.model.common.paging.PagingRequest;
import org.gbif.api.model.common.paging.PagingResponse;
import org.gbif.api.model.registry.search.collections.KeyCodeNameResult;
@@ -27,8 +46,10 @@
import org.gbif.api.service.collections.ChangeSuggestionService;
import org.gbif.api.service.collections.CollectionEntityService;
import org.gbif.api.service.collections.CollectionService;
+import org.gbif.api.service.collections.DescriptorsService;
import org.gbif.api.vocabulary.Country;
import org.gbif.api.vocabulary.GbifRegion;
+import org.gbif.api.vocabulary.Rank;
import org.gbif.registry.service.collections.batch.CollectionBatchService;
import org.gbif.registry.service.collections.duplicates.CollectionDuplicatesService;
import org.gbif.registry.service.collections.duplicates.DuplicatesService;
@@ -42,19 +63,10 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.web.server.LocalServerPort;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.UUID;
-import java.util.stream.Collectors;
-
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.when;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.web.multipart.MultipartFile;
public class CollectionResourceIT
extends BaseCollectionEntityResourceIT {
@@ -68,6 +80,7 @@ public class CollectionResourceIT
@MockBean private CollectionChangeSuggestionService collectionChangeSuggestionService;
@MockBean private CollectionBatchService collectionBatchService;
+ @MockBean private DescriptorsService descriptorsService;
@Autowired
public CollectionResourceIT(
@@ -92,7 +105,7 @@ public void listTest() {
when(collectionService.list(any(CollectionSearchRequest.class)))
.thenReturn(new PagingResponse<>(new PagingRequest(), Long.valueOf(views.size()), views));
- CollectionSearchRequest req = new CollectionSearchRequest();
+ CollectionSearchRequest req = CollectionSearchRequest.builder().build();
req.setCity("city");
req.setInstitution(UUID.randomUUID());
req.setCountry(Collections.singletonList(Country.DENMARK));
@@ -118,7 +131,7 @@ public void listAndGetAsLatimerCoreTest() {
.thenReturn(new PagingResponse<>(new PagingRequest(), Long.valueOf(orgs.size()), orgs));
PagingResponse result =
- getClient().listAsLatimerCore(new CollectionSearchRequest());
+ getClient().listAsLatimerCore(CollectionSearchRequest.builder().build());
assertEquals(orgs.size(), result.getResults().size());
when(collectionService.getAsLatimerCore(any(UUID.class))).thenReturn(o1);
@@ -169,7 +182,7 @@ public void listDeletedTest() {
when(collectionService.listDeleted(any(CollectionSearchRequest.class)))
.thenReturn(new PagingResponse<>(new PagingRequest(), Long.valueOf(views.size()), views));
- CollectionSearchRequest request = new CollectionSearchRequest();
+ CollectionSearchRequest request = CollectionSearchRequest.builder().build();
request.setReplacedBy(UUID.randomUUID());
PagingResponse result = getClient().listDeleted(request);
assertEquals(views.size(), result.getResults().size());
@@ -223,6 +236,136 @@ public void createFromDatasetTest() {
assertEquals(institutionKey, getClient().createFromDataset(params));
}
+ @SneakyThrows
+ @Test
+ public void createDescriptorGroupTest() {
+ when(descriptorsService.createDescriptorGroup(any(), any(), any(), any(), any()))
+ .thenReturn(1L);
+
+ Resource descriptorsResource = new ClassPathResource("collections/descriptors.csv");
+ MultipartFile descriptorsFile =
+ new MockMultipartFile("descriptorsFile", descriptorsResource.getInputStream());
+
+ assertEquals(
+ 1L,
+ getClient()
+ .createDescriptorGroup(
+ UUID.randomUUID(), ExportFormat.CSV, descriptorsFile, "title", "desc"));
+ }
+
+ @SneakyThrows
+ @Test
+ public void updateDescriptorGroupTest() {
+ UUID collectionKey = UUID.randomUUID();
+ DescriptorGroup descriptorGroup = new DescriptorGroup();
+ descriptorGroup.setCollectionKey(collectionKey);
+ descriptorGroup.setTitle("title");
+
+ when(descriptorsService.getDescriptorGroup(anyLong())).thenReturn(descriptorGroup);
+ doNothing()
+ .when(descriptorsService)
+ .updateDescriptorGroup(anyLong(), any(), any(), anyString(), anyString());
+
+ Resource descriptorsResource = new ClassPathResource("collections/descriptors.csv");
+ MultipartFile descriptorsFile =
+ new MockMultipartFile("descriptorsFile", descriptorsResource.getInputStream());
+
+ assertDoesNotThrow(
+ () ->
+ getClient()
+ .updateDescriptorGroup(
+ collectionKey, 1L, ExportFormat.CSV, descriptorsFile, "title", "desc"));
+ }
+
+ @Test
+ public void getDescriptorGroupTest() {
+ UUID collectionKey = UUID.randomUUID();
+ DescriptorGroup descriptorGroup = new DescriptorGroup();
+ descriptorGroup.setCollectionKey(collectionKey);
+ descriptorGroup.setTitle("title");
+
+ when(resourceNotFoundService.entityExists(any(), any())).thenReturn(true);
+ when(descriptorsService.getDescriptorGroup(1L)).thenReturn(descriptorGroup);
+
+ assertEquals(descriptorGroup, getClient().getCollectionDescriptorGroup(collectionKey, 1L));
+ }
+
+ @Test
+ public void listDescriptorGroupTest() {
+ DescriptorGroup descriptorGroup = new DescriptorGroup();
+ descriptorGroup.setCollectionKey(UUID.randomUUID());
+ descriptorGroup.setTitle("title");
+
+ when(resourceNotFoundService.entityExists(any(), any())).thenReturn(true);
+ when(descriptorsService.listDescriptorGroups(
+ any(UUID.class), any(DescriptorGroupSearchRequest.class)))
+ .thenReturn(new PagingResponse<>(0, 10, 1L, Collections.singletonList(descriptorGroup)));
+
+ assertEquals(
+ 1,
+ getClient()
+ .listCollectionDescriptorGroups(
+ UUID.randomUUID(), DescriptorGroupSearchRequest.builder().q("foo").build())
+ .getResults()
+ .size());
+ }
+
+ @Test
+ public void listDescriptorsTest() {
+ Descriptor descriptor = new Descriptor();
+ descriptor.setDescriptorGroupKey(1L);
+ descriptor.setUsageRank(Rank.ABERRATION);
+ descriptor.setCountry(Country.SPAIN);
+
+ when(resourceNotFoundService.entityExists(any(), any())).thenReturn(true);
+ when(descriptorsService.listDescriptors(any()))
+ .thenReturn(new PagingResponse<>(0, 10, 1L, Collections.singletonList(descriptor)));
+
+ assertEquals(
+ 1,
+ getClient()
+ .listCollectionDescriptors(
+ UUID.randomUUID(),
+ 1L,
+ DescriptorSearchRequest.builder().q("foo").individualCount("1,10").build())
+ .getResults()
+ .size());
+ }
+
+ @Test
+ public void getDescriptorTest() {
+ UUID collectionKey = UUID.randomUUID();
+ Descriptor descriptor = new Descriptor();
+ descriptor.setDescriptorGroupKey(1L);
+ descriptor.setUsageRank(Rank.ABERRATION);
+ descriptor.setCountry(Country.SPAIN);
+
+ DescriptorGroup descriptorGroup = new DescriptorGroup();
+ descriptorGroup.setCollectionKey(collectionKey);
+ descriptorGroup.setTitle("title");
+
+ when(resourceNotFoundService.entityExists(any(), any())).thenReturn(true);
+ when(descriptorsService.getDescriptor(anyLong())).thenReturn(descriptor);
+ when(descriptorsService.getDescriptorGroup(anyLong())).thenReturn(descriptorGroup);
+
+ assertEquals(descriptor, getClient().getCollectionDescriptor(collectionKey, 1L, 1L));
+ }
+
+ @Test
+ public void deleteDescriptorTest() {
+ UUID collectionKey = UUID.randomUUID();
+
+ DescriptorGroup descriptorGroup = new DescriptorGroup();
+ descriptorGroup.setKey(1L);
+ descriptorGroup.setCollectionKey(collectionKey);
+ descriptorGroup.setTitle("title");
+
+ when(resourceNotFoundService.entityExists(any(), any())).thenReturn(true);
+ when(descriptorsService.getDescriptorGroup(anyLong())).thenReturn(descriptorGroup);
+
+ assertDoesNotThrow(() -> getClient().deleteCollectionDescriptorGroup(collectionKey, 1L));
+ }
+
protected CollectionClient getClient() {
return (CollectionClient) baseClient;
}
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/CollectionsSearchResourceTest.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/CollectionsSearchResourceTest.java
index 558ec3a056..056ef54a5b 100644
--- a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/CollectionsSearchResourceTest.java
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/CollectionsSearchResourceTest.java
@@ -13,29 +13,31 @@
*/
package org.gbif.registry.ws.it.collections.resource;
-import org.gbif.api.model.collections.search.CollectionsSearchResponse;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import org.gbif.api.model.collections.request.CollectionDescriptorsSearchRequest;
+import org.gbif.api.model.collections.request.InstitutionSearchRequest;
+import org.gbif.api.model.collections.search.CollectionSearchResponse;
+import org.gbif.api.model.collections.search.CollectionsFullSearchResponse;
+import org.gbif.api.model.collections.search.Highlight;
+import org.gbif.api.model.collections.search.InstitutionSearchResponse;
+import org.gbif.api.model.common.paging.PagingResponse;
import org.gbif.api.vocabulary.Country;
-import org.gbif.registry.search.dataset.service.collections.CollectionsSearchService;
+import org.gbif.registry.service.collections.CollectionsSearchService;
import org.gbif.registry.ws.client.collections.CollectionsSearchClient;
import org.gbif.registry.ws.it.fixtures.RequestTestFixture;
import org.gbif.registry.ws.it.fixtures.TestConstants;
import org.gbif.ws.client.filter.SimplePrincipalProvider;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.UUID;
-
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.parallel.Execution;
-import org.junit.jupiter.api.parallel.ExecutionMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.web.server.LocalServerPort;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.Mockito.when;
-
-@Execution(ExecutionMode.CONCURRENT)
public class CollectionsSearchResourceTest extends BaseResourceIT {
@MockBean private CollectionsSearchService collectionsSearchService;
@@ -56,23 +58,62 @@ public CollectionsSearchResourceTest(
@Test
public void searchTest() {
String q = "foo";
- boolean highlight = true;
+ boolean hl = true;
int limit = 10;
- CollectionsSearchResponse response = new CollectionsSearchResponse();
+ CollectionsFullSearchResponse response = new CollectionsFullSearchResponse();
response.setCode("c1");
response.setInstitutionKey(UUID.randomUUID());
- CollectionsSearchResponse.Match match = new CollectionsSearchResponse.Match();
- match.setField("field1");
- match.setSnippet("snippet");
- response.setMatches(Collections.singleton(match));
+ Highlight highlight = new Highlight();
+ highlight.setField("field1");
+ highlight.setSnippet("snippet");
+ response.setHighlights(Collections.singleton(highlight));
- when(collectionsSearchService.search(q, highlight, null, null, Country.SPAIN, limit))
+ when(collectionsSearchService.search(q, hl, null, null, Country.SPAIN, limit))
.thenReturn(Collections.singletonList(response));
- List responseReturned =
- collectionsSearchClient.searchCollections(q, highlight, null, null, Country.SPAIN, limit);
+ List responseReturned =
+ collectionsSearchClient.searchCrossEntities(q, hl, null, null, Country.SPAIN, limit);
assertEquals(1, responseReturned.size());
assertEquals(response, responseReturned.get(0));
}
+
+ @Test
+ public void searchInstitutionsTest() {
+ InstitutionSearchResponse response = new InstitutionSearchResponse();
+ response.setCode("c1");
+ response.setKey(UUID.randomUUID());
+ Highlight highlight = new Highlight();
+ highlight.setField("field1");
+ highlight.setSnippet("snippet");
+ response.setHighlights(Collections.singleton(highlight));
+
+ when(collectionsSearchService.searchInstitutions(any()))
+ .thenReturn(new PagingResponse<>(0, 20, 1L, Collections.singletonList(response)));
+
+ PagingResponse responseReturned =
+ collectionsSearchClient.searchInstitutions(InstitutionSearchRequest.builder().build());
+ assertEquals(1, responseReturned.getResults().size());
+ assertEquals(response, responseReturned.getResults().get(0));
+ }
+
+ @Test
+ public void searchCollectionsTest() {
+ CollectionSearchResponse response = new CollectionSearchResponse();
+ response.setCode("c1");
+ response.setKey(UUID.randomUUID());
+ Highlight highlight = new Highlight();
+ highlight.setField("field1");
+ highlight.setSnippet("snippet");
+ response.setHighlights(Collections.singleton(highlight));
+
+ when(collectionsSearchService.searchCollections(any()))
+ .thenReturn(new PagingResponse<>(0, 20, 1L, Collections.singletonList(response)));
+
+ PagingResponse responseReturned =
+ collectionsSearchClient.searchCollections(
+ CollectionDescriptorsSearchRequest.builder().build());
+ assertEquals(1, responseReturned.getResults().size());
+ assertEquals(response, responseReturned.getResults().get(0));
+ }
}
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/InstitutionResourceIT.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/InstitutionResourceIT.java
index 286591e3e6..a0fd607946 100644
--- a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/InstitutionResourceIT.java
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/resource/InstitutionResourceIT.java
@@ -13,6 +13,17 @@
*/
package org.gbif.registry.ws.it.collections.resource;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
import org.gbif.api.model.collections.Institution;
import org.gbif.api.model.collections.InstitutionImportParams;
import org.gbif.api.model.collections.latimercore.OrganisationalUnit;
@@ -46,18 +57,6 @@
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.web.server.LocalServerPort;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.UUID;
-
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.when;
-
public class InstitutionResourceIT
extends BaseCollectionEntityResourceIT {
@@ -95,7 +94,7 @@ public void listTest() {
new PagingResponse<>(
new PagingRequest(), Long.valueOf(institutions.size()), institutions));
- InstitutionSearchRequest req = new InstitutionSearchRequest();
+ InstitutionSearchRequest req = InstitutionSearchRequest.builder().build();
req.setCity("city");
req.setContact(UUID.randomUUID());
req.setCountry(Collections.singletonList(Country.DENMARK));
@@ -122,7 +121,7 @@ public void listAndGetAsLatimerCoreTest() {
.thenReturn(new PagingResponse<>(new PagingRequest(), Long.valueOf(orgs.size()), orgs));
PagingResponse result =
- getClient().listAsLatimerCore(new InstitutionSearchRequest());
+ getClient().listAsLatimerCore(InstitutionSearchRequest.builder().build());
assertEquals(orgs.size(), result.getResults().size());
when(institutionService.getAsLatimerCore(any(UUID.class))).thenReturn(o1);
@@ -162,7 +161,8 @@ public void listAsGeoJsonTest() {
when(institutionService.listGeojson(any(InstitutionSearchRequest.class)))
.thenReturn(featureCollection);
- FeatureCollection result = getClient().listAsGeoJson(new InstitutionSearchRequest());
+ FeatureCollection result =
+ getClient().listAsGeoJson(InstitutionSearchRequest.builder().build());
assertEquals(featureCollection.getFeatures().size(), result.getFeatures().size());
}
@@ -195,7 +195,7 @@ public void listDeletedTest() {
new PagingResponse<>(
new PagingRequest(), Long.valueOf(institutions.size()), institutions));
- InstitutionSearchRequest request = new InstitutionSearchRequest();
+ InstitutionSearchRequest request = InstitutionSearchRequest.builder().build();
request.setReplacedBy(UUID.randomUUID());
PagingResponse result = getClient().listDeleted(request);
assertEquals(institutions.size(), result.getResults().size());
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/CollectionServiceIT.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/CollectionServiceIT.java
index 366d9e9923..cfcb87cb23 100644
--- a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/CollectionServiceIT.java
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/CollectionServiceIT.java
@@ -13,15 +13,21 @@
*/
package org.gbif.registry.ws.it.collections.service;
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.net.URI;
+import java.util.*;
+import java.util.stream.Collectors;
+import javax.validation.ConstraintViolationException;
+import javax.validation.ValidationException;
+import org.gbif.api.model.collections.*;
import org.gbif.api.model.collections.Address;
import org.gbif.api.model.collections.Collection;
-import org.gbif.api.model.collections.*;
import org.gbif.api.model.collections.duplicates.Duplicate;
import org.gbif.api.model.collections.duplicates.DuplicatesResult;
import org.gbif.api.model.collections.latimercore.*;
import org.gbif.api.model.collections.request.CollectionSearchRequest;
import org.gbif.api.model.collections.view.CollectionView;
-import org.gbif.api.model.common.paging.PagingRequest;
import org.gbif.api.model.common.paging.PagingResponse;
import org.gbif.api.model.registry.Dataset;
import org.gbif.api.model.registry.Identifier;
@@ -43,14 +49,6 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import javax.validation.ConstraintViolationException;
-import javax.validation.ValidationException;
-import java.net.URI;
-import java.util.*;
-import java.util.stream.Collectors;
-
-import static org.junit.jupiter.api.Assertions.*;
-
/** Tests the {@link CollectionService}. */
public class CollectionServiceIT extends BaseCollectionEntityServiceIT {
@@ -132,7 +130,11 @@ public void listTest() {
// query param
PagingResponse response =
collectionService.list(
- CollectionSearchRequest.builder().query("dummy").page(DEFAULT_PAGE).build());
+ CollectionSearchRequest.builder()
+ .q("dummy")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(3, response.getResults().size());
response =
@@ -143,55 +145,96 @@ public void listTest() {
// empty queries are ignored and return all elements
response =
collectionService.list(
- CollectionSearchRequest.builder().query("").page(DEFAULT_PAGE).build());
+ CollectionSearchRequest.builder()
+ .q("")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(3, response.getResults().size());
response =
collectionService.list(
- CollectionSearchRequest.builder().query("city").page(DEFAULT_PAGE).build());
+ CollectionSearchRequest.builder()
+ .q("city")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(1, response.getResults().size());
assertEquals(key1, response.getResults().get(0).getCollection().getKey());
response =
collectionService.list(
- CollectionSearchRequest.builder().query("city2").page(DEFAULT_PAGE).build());
+ CollectionSearchRequest.builder()
+ .q("city2")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(1, response.getResults().size());
assertEquals(key2, response.getResults().get(0).getCollection().getKey());
assertEquals(
3,
collectionService
- .list(CollectionSearchRequest.builder().query("c").page(DEFAULT_PAGE).build())
+ .list(
+ CollectionSearchRequest.builder()
+ .q("c")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
2,
collectionService
- .list(CollectionSearchRequest.builder().query("dum add").page(DEFAULT_PAGE).build())
+ .list(
+ CollectionSearchRequest.builder()
+ .q("dum add")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
0,
collectionService
- .list(CollectionSearchRequest.builder().query("<").page(DEFAULT_PAGE).build())
+ .list(
+ CollectionSearchRequest.builder()
+ .q("<")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
0,
collectionService
- .list(CollectionSearchRequest.builder().query("\"<\"").page(DEFAULT_PAGE).build())
+ .list(
+ CollectionSearchRequest.builder()
+ .q("\"<\"")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
3,
collectionService
- .list(CollectionSearchRequest.builder().page(DEFAULT_PAGE).build())
+ .list(
+ CollectionSearchRequest.builder()
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
3,
collectionService
- .list(CollectionSearchRequest.builder().query(" ").page(DEFAULT_PAGE).build())
+ .list(
+ CollectionSearchRequest.builder()
+ .q(" ")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
@@ -199,33 +242,58 @@ public void listTest() {
assertEquals(
1,
collectionService
- .list(CollectionSearchRequest.builder().code("c1").page(DEFAULT_PAGE).build())
+ .list(
+ CollectionSearchRequest.builder()
+ .code("c1")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
1,
collectionService
- .list(CollectionSearchRequest.builder().name("n2").page(DEFAULT_PAGE).build())
+ .list(
+ CollectionSearchRequest.builder()
+ .name("n2")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
1,
collectionService
.list(
- CollectionSearchRequest.builder().code("c1").name("n1").page(DEFAULT_PAGE).build())
+ CollectionSearchRequest.builder()
+ .code("c1")
+ .name("n1")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
0,
collectionService
.list(
- CollectionSearchRequest.builder().code("c2").name("n1").page(DEFAULT_PAGE).build())
+ CollectionSearchRequest.builder()
+ .code("c2")
+ .name("n1")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
2,
collectionService
- .list(CollectionSearchRequest.builder().active(true).page(DEFAULT_PAGE).build())
+ .list(
+ CollectionSearchRequest.builder()
+ .active(true)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
@@ -234,7 +302,8 @@ public void listTest() {
.list(
CollectionSearchRequest.builder()
.accessionStatus(Collections.singletonList("Institutional"))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -244,7 +313,8 @@ public void listTest() {
.list(
CollectionSearchRequest.builder()
.accessionStatus(Collections.singletonList("Project"))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -254,7 +324,8 @@ public void listTest() {
.list(
CollectionSearchRequest.builder()
.contentTypes(Collections.singletonList("Archaeological"))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -264,7 +335,8 @@ public void listTest() {
.list(
CollectionSearchRequest.builder()
.contentTypes(Arrays.asList("Archaeological", "Biological"))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -274,7 +346,8 @@ public void listTest() {
.list(
CollectionSearchRequest.builder()
.preservationTypes(Collections.singletonList("SampleDried"))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -284,7 +357,8 @@ public void listTest() {
.list(
CollectionSearchRequest.builder()
.personalCollection(true)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -294,14 +368,22 @@ public void listTest() {
1,
collectionService
.list(
- CollectionSearchRequest.builder().alternativeCode("alt").page(DEFAULT_PAGE).build())
+ CollectionSearchRequest.builder()
+ .alternativeCode("alt")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
0,
collectionService
.list(
- CollectionSearchRequest.builder().alternativeCode("foo").page(DEFAULT_PAGE).build())
+ CollectionSearchRequest.builder()
+ .alternativeCode("foo")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
@@ -311,7 +393,8 @@ public void listTest() {
.list(
CollectionSearchRequest.builder()
.country(Collections.singletonList(Country.SPAIN))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults();
assertEquals(1, results.size());
@@ -322,7 +405,8 @@ public void listTest() {
.list(
CollectionSearchRequest.builder()
.country(Collections.singletonList(Country.AFGHANISTAN))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -332,7 +416,8 @@ public void listTest() {
.list(
CollectionSearchRequest.builder()
.country(Arrays.asList(Country.SPAIN, Country.DENMARK))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -342,7 +427,8 @@ public void listTest() {
.list(
CollectionSearchRequest.builder()
.gbifRegion(Collections.singletonList(GbifRegion.EUROPE))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -353,7 +439,8 @@ public void listTest() {
CollectionSearchRequest.builder()
.country(Collections.singletonList(Country.SPAIN))
.gbifRegion(Collections.singletonList(GbifRegion.ASIA))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -361,14 +448,24 @@ public void listTest() {
// city
results =
collectionService
- .list(CollectionSearchRequest.builder().city("city2").page(DEFAULT_PAGE).build())
+ .list(
+ CollectionSearchRequest.builder()
+ .city("city2")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults();
assertEquals(1, results.size());
assertEquals(key2, results.get(0).getCollection().getKey());
assertEquals(
0,
collectionService
- .list(CollectionSearchRequest.builder().city("foo").page(DEFAULT_PAGE).build())
+ .list(
+ CollectionSearchRequest.builder()
+ .city("foo")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
@@ -380,7 +477,12 @@ public void listTest() {
assertEquals(
1,
collectionService
- .list(CollectionSearchRequest.builder().query("city3").page(DEFAULT_PAGE).build())
+ .list(
+ CollectionSearchRequest.builder()
+ .q("city3")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
@@ -390,7 +492,8 @@ public void listTest() {
.list(
CollectionSearchRequest.builder()
.displayOnNHCPortal(true)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -400,7 +503,11 @@ public void listTest() {
1,
collectionService
.list(
- CollectionSearchRequest.builder().numberSpecimens("100").page(DEFAULT_PAGE).build())
+ CollectionSearchRequest.builder()
+ .numberSpecimens("100")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
@@ -408,7 +515,11 @@ public void listTest() {
0,
collectionService
.list(
- CollectionSearchRequest.builder().numberSpecimens("98").page(DEFAULT_PAGE).build())
+ CollectionSearchRequest.builder()
+ .numberSpecimens("98")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
@@ -418,7 +529,8 @@ public void listTest() {
.list(
CollectionSearchRequest.builder()
.numberSpecimens("* , 100")
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -429,7 +541,8 @@ public void listTest() {
.list(
CollectionSearchRequest.builder()
.numberSpecimens("97,300")
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -440,7 +553,8 @@ public void listTest() {
.list(
CollectionSearchRequest.builder()
.sortBy(CollectionsSortField.NUMBER_SPECIMENS)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.get(0)
@@ -454,7 +568,8 @@ public void listTest() {
CollectionSearchRequest.builder()
.sortBy(CollectionsSortField.NUMBER_SPECIMENS)
.sortOrder(SortOrder.DESC)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.get(0)
@@ -465,7 +580,12 @@ public void listTest() {
assertEquals(
0,
collectionService
- .list(CollectionSearchRequest.builder().query("city3").page(DEFAULT_PAGE).build())
+ .list(
+ CollectionSearchRequest.builder()
+ .q("city3")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
}
@@ -499,7 +619,8 @@ public void listByInstitutionTest() {
collectionService.list(
CollectionSearchRequest.builder()
.institution(institutionKey1)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(2, response.getResults().size());
@@ -507,7 +628,8 @@ public void listByInstitutionTest() {
collectionService.list(
CollectionSearchRequest.builder()
.institution(institutionKey2)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(1, response.getResults().size());
@@ -515,7 +637,8 @@ public void listByInstitutionTest() {
collectionService.list(
CollectionSearchRequest.builder()
.institution(UUID.randomUUID())
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(0, response.getResults().size());
@@ -523,7 +646,8 @@ public void listByInstitutionTest() {
collectionService.list(
CollectionSearchRequest.builder()
.institutionKeys(Collections.singletonList(institutionKey1))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(2, response.getResults().size());
@@ -531,16 +655,18 @@ public void listByInstitutionTest() {
collectionService.list(
CollectionSearchRequest.builder()
.institutionKeys(Arrays.asList(institutionKey1, institutionKey2))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(3, response.getResults().size());
response =
collectionService.list(
CollectionSearchRequest.builder()
- .query(collection1.getCode())
+ .q(collection1.getCode())
.institutionKeys(Arrays.asList(institutionKey1, institutionKey2))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(1, response.getResults().size());
}
@@ -750,36 +876,40 @@ public void listMultipleParamsTest() {
PagingResponse response =
collectionService.list(
CollectionSearchRequest.builder()
- .query("code1")
+ .q("code1")
.institution(institutionKey1)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(1, response.getResults().size());
response =
collectionService.list(
CollectionSearchRequest.builder()
- .query("foo")
+ .q("foo")
.institution(institutionKey1)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(0, response.getResults().size());
response =
collectionService.list(
CollectionSearchRequest.builder()
- .query("code2")
+ .q("code2")
.institution(institutionKey2)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(0, response.getResults().size());
response =
collectionService.list(
CollectionSearchRequest.builder()
- .query("code2")
+ .q("code2")
.institution(institutionKey1)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(1, response.getResults().size());
@@ -797,36 +927,40 @@ public void listMultipleParamsTest() {
response =
collectionService.list(
CollectionSearchRequest.builder()
- .query("Name1")
+ .q("Name1")
.institution(institutionKey1)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(1, response.getResults().size());
response =
collectionService.list(
CollectionSearchRequest.builder()
- .query("abcde")
+ .q("abcde")
.institution(institutionKey1)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(1, response.getResults().size());
response =
collectionService.list(
CollectionSearchRequest.builder()
- .query("aa1@aa.com")
+ .q("aa1@aa.com")
.institution(institutionKey1)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(1, response.getResults().size());
response =
collectionService.list(
CollectionSearchRequest.builder()
- .query("aves")
+ .q("aves")
.institution(institutionKey1)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(1, response.getResults().size());
}
@@ -885,7 +1019,7 @@ public void listDeletedTest() {
collection4.setName("Collection name4");
UUID key4 = collectionService.create(collection4);
- CollectionSearchRequest searchRequest = new CollectionSearchRequest();
+ CollectionSearchRequest searchRequest = CollectionSearchRequest.builder().build();
searchRequest.setReplacedBy(key4);
assertEquals(0, collectionService.listDeleted(searchRequest).getResults().size());
collectionService.replace(key3, key4);
@@ -901,22 +1035,29 @@ public void listWithoutParametersTest() {
UUID key3 = collectionService.create(collection3);
PagingResponse response =
- collectionService.list(CollectionSearchRequest.builder().page(DEFAULT_PAGE).build());
+ collectionService.list(
+ CollectionSearchRequest.builder()
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(3, response.getResults().size());
collectionService.delete(key3);
- response = collectionService.list(CollectionSearchRequest.builder().page(DEFAULT_PAGE).build());
+ response =
+ collectionService.list(
+ CollectionSearchRequest.builder()
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(2, response.getResults().size());
response =
- collectionService.list(
- CollectionSearchRequest.builder().page(new PagingRequest(0L, 1)).build());
+ collectionService.list(CollectionSearchRequest.builder().limit(1).offset(0L).build());
assertEquals(1, response.getResults().size());
response =
- collectionService.list(
- CollectionSearchRequest.builder().page(new PagingRequest(0L, 0)).build());
+ collectionService.list(CollectionSearchRequest.builder().limit(0).offset(0L).build());
assertEquals(0, response.getResults().size());
}
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/CollectionsSearchIT.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/CollectionsSearchIT.java
index eabe0062c7..62cd06b7fc 100644
--- a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/CollectionsSearchIT.java
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/CollectionsSearchIT.java
@@ -13,33 +13,46 @@
*/
package org.gbif.registry.ws.it.collections.service;
+import static org.gbif.registry.domain.collections.TypeParam.COLLECTION;
+import static org.gbif.registry.domain.collections.TypeParam.INSTITUTION;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import lombok.SneakyThrows;
import org.gbif.api.model.collections.Address;
import org.gbif.api.model.collections.AlternativeCode;
import org.gbif.api.model.collections.Collection;
import org.gbif.api.model.collections.Institution;
-import org.gbif.api.model.collections.search.CollectionsSearchResponse;
+import org.gbif.api.model.collections.request.CollectionDescriptorsSearchRequest;
+import org.gbif.api.model.collections.request.InstitutionSearchRequest;
+import org.gbif.api.model.collections.search.CollectionSearchResponse;
+import org.gbif.api.model.collections.search.CollectionsFullSearchResponse;
+import org.gbif.api.model.collections.search.InstitutionSearchResponse;
+import org.gbif.api.model.common.export.ExportFormat;
+import org.gbif.api.model.common.paging.PagingResponse;
import org.gbif.api.model.registry.Identifier;
import org.gbif.api.service.collections.CollectionService;
+import org.gbif.api.service.collections.DescriptorsService;
import org.gbif.api.service.collections.InstitutionService;
+import org.gbif.api.vocabulary.CollectionsSortField;
import org.gbif.api.vocabulary.Country;
import org.gbif.api.vocabulary.IdentifierType;
+import org.gbif.api.vocabulary.SortOrder;
+import org.gbif.api.vocabulary.TypeStatus;
import org.gbif.registry.database.TestCaseDatabaseInitializer;
-import org.gbif.registry.search.dataset.service.collections.CollectionsSearchService;
+import org.gbif.registry.service.collections.CollectionsSearchService;
+import org.gbif.registry.test.mocks.NubResourceClientMock;
import org.gbif.ws.client.filter.SimplePrincipalProvider;
-
-import java.util.Collections;
-import java.util.List;
-
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.springframework.beans.factory.annotation.Autowired;
-
-import static org.gbif.registry.domain.collections.TypeParam.COLLECTION;
-import static org.gbif.registry.domain.collections.TypeParam.INSTITUTION;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.util.StreamUtils;
/** Tests the {@link CollectionsSearchService} * */
public class CollectionsSearchIT extends BaseServiceIT {
@@ -50,6 +63,7 @@ public class CollectionsSearchIT extends BaseServiceIT {
private final CollectionsSearchService searchService;
private final InstitutionService institutionService;
private final CollectionService collectionService;
+ private final DescriptorsService descriptorsService;
private final Institution i1 = new Institution();
private final Institution i11 = new Institution();
@@ -62,13 +76,16 @@ public CollectionsSearchIT(
SimplePrincipalProvider simplePrincipalProvider,
CollectionsSearchService collectionsSearchService,
InstitutionService institutionService,
- CollectionService collectionService) {
+ CollectionService collectionService,
+ DescriptorsService descriptorsService) {
super(simplePrincipalProvider);
this.searchService = collectionsSearchService;
this.institutionService = institutionService;
this.collectionService = collectionService;
+ this.descriptorsService = descriptorsService;
}
+ @SneakyThrows
@BeforeEach
public void loadData() {
i1.setCode("I1");
@@ -100,51 +117,77 @@ public void loadData() {
addressC1.setProvince("Asturias");
addressC1.setAddress("fake street");
c1.setAddress(addressC1);
+ c1.setNumberSpecimens(4000);
c1.setDisplayOnNHCPortal(false);
collectionService.create(c1);
+ descriptorsService.createDescriptorGroup(
+ StreamUtils.copyToByteArray(
+ new ClassPathResource("collections/descriptors.csv").getInputStream()),
+ ExportFormat.TSV,
+ "My personal descriptor set",
+ "description",
+ c1.getKey());
+
+ descriptorsService.createDescriptorGroup(
+ StreamUtils.copyToByteArray(
+ new ClassPathResource("collections/descriptors2.csv").getInputStream()),
+ ExportFormat.TSV,
+ "My descriptor set 2",
+ "description",
+ c1.getKey());
+
c2.setCode("C2");
c2.setName("Collection 2");
+ c2.setNumberSpecimens(1000);
c2.setInstitutionKey(i2.getKey());
c2.setAlternativeCodes(Collections.singletonList(new AlternativeCode("CC2", "test")));
c2.getIdentifiers().add(new Identifier(IdentifierType.LSID, "lsid-coll"));
collectionService.create(c2);
+
+ descriptorsService.createDescriptorGroup(
+ StreamUtils.copyToByteArray(
+ new ClassPathResource("collections/descriptors3.csv").getInputStream()),
+ ExportFormat.TSV,
+ "My descriptor set 3",
+ "unusual description",
+ c2.getKey());
}
@Test
public void searchByCodeTest() {
- List responses =
+ List responses =
searchService.search("I1", true, null, null, null, 10);
assertEquals(3, responses.size());
assertEquals(i1.getKey(), responses.get(0).getKey());
- assertEquals(1, responses.get(0).getMatches().size());
+ assertEquals(1, responses.get(0).getHighlights().size());
responses = searchService.search("i1", true, null, null, null, 10);
assertEquals(3, responses.size());
assertEquals(i11.getKey(), responses.get(0).getKey());
- assertEquals(2, responses.get(0).getMatches().size());
+ assertEquals(2, responses.get(0).getHighlights().size());
}
@Test
public void searchByNameTest() {
- List responses =
+ List responses =
searchService.search("Collection", true, null, null, null, 10);
assertEquals(2, responses.size());
responses = searchService.search("Collection 2", true, null, null, null, 10);
assertEquals(2, responses.size());
- assertEquals(1, responses.get(0).getMatches().size());
- assertEquals(1, responses.get(1).getMatches().size());
+ assertEquals(1, responses.get(0).getHighlights().size());
+ assertEquals(1, responses.get(1).getHighlights().size());
responses = searchService.search("Colllection 1", true, null, null, null, 10);
assertEquals(2, responses.size());
- assertEquals(1, responses.get(0).getMatches().size());
- assertEquals(1, responses.get(1).getMatches().size());
+ assertEquals(1, responses.get(0).getHighlights().size());
+ assertEquals(1, responses.get(1).getHighlights().size());
}
@Test
public void searchByAlternativeCodesTest() {
- List responses =
+ List responses =
searchService.search("II2", true, null, null, null, 10);
assertEquals(1, responses.size());
assertEquals(i2.getKey(), responses.get(0).getKey());
@@ -155,36 +198,36 @@ public void searchByAlternativeCodesTest() {
@Test
public void searchByAddressFieldsTest() {
- List responses =
+ List responses =
searchService.search("street", true, null, null, null, 10);
assertEquals(2, responses.size());
responses = searchService.search(Country.SPAIN.getIso2LetterCode(), true, null, null, null, 10);
assertEquals(1, responses.size());
assertEquals(c1.getKey(), responses.get(0).getKey());
- assertEquals(1, responses.get(0).getMatches().size());
+ assertEquals(1, responses.get(0).getHighlights().size());
responses = searchService.search("oviedo", true, null, null, null, 10);
assertEquals(1, responses.size());
assertEquals(c1.getKey(), responses.get(0).getKey());
- assertEquals(1, responses.get(0).getMatches().size());
+ assertEquals(1, responses.get(0).getHighlights().size());
responses = searchService.search("street asturias", true, null, null, null, 10);
assertEquals(1, responses.size());
assertEquals(c1.getKey(), responses.get(0).getKey());
- assertEquals(2, responses.get(0).getMatches().size());
+ assertEquals(2, responses.get(0).getHighlights().size());
}
@Test
public void searchWithoutHighlightTest() {
- List responses =
+ List responses =
searchService.search("Collection", false, null, null, null, 10);
- assertNull(responses.get(0).getMatches());
+ assertTrue(responses.get(0).getHighlights().isEmpty());
}
@Test
public void noMatchesTest() {
- List responses =
+ List responses =
searchService.search("nothing", false, null, null, null, 10);
assertEquals(0, responses.size());
@@ -197,7 +240,7 @@ public void noMatchesTest() {
@Test
public void displayOnNHCPortalTest() {
- List responses =
+ List responses =
searchService.search(null, false, null, true, null, 10);
assertEquals(3, responses.size());
@@ -207,7 +250,7 @@ public void displayOnNHCPortalTest() {
@Test
public void typeParamTest() {
- List responses =
+ List responses =
searchService.search(null, false, INSTITUTION, null, null, 10);
assertEquals(3, responses.size());
assertTrue(responses.stream().allMatch(d -> d.getType().equals("institution")));
@@ -222,7 +265,7 @@ public void typeParamTest() {
@Test
public void countryFilterTest() {
- List responses =
+ List responses =
searchService.search(null, true, null, null, Country.SPAIN, 10);
assertEquals(1, responses.size());
assertEquals(c1.getKey(), responses.get(0).getKey());
@@ -239,9 +282,217 @@ public void countryFilterTest() {
responses = searchService.search("C1", true, null, null, Country.SPAIN, 10);
assertEquals(1, responses.size());
assertEquals(c1.getKey(), responses.get(0).getKey());
- assertEquals(1, responses.get(0).getMatches().size());
+ assertEquals(1, responses.get(0).getHighlights().size());
responses = searchService.search("C1", true, null, null, Country.DENMARK, 10);
assertEquals(0, responses.size());
}
+
+ @Test
+ public void searchInstitutionsTest() {
+ PagingResponse response =
+ searchService.searchInstitutions(InstitutionSearchRequest.builder().build());
+ assertEquals(3, response.getResults().size());
+ assertEquals(3, response.getCount());
+
+ assertEquals(
+ 1,
+ searchService
+ .searchInstitutions(
+ InstitutionSearchRequest.builder()
+ .country(Collections.singletonList(i1.getAddress().getCountry()))
+ .build())
+ .getResults()
+ .size());
+
+ assertEquals(
+ 1,
+ searchService
+ .searchInstitutions(InstitutionSearchRequest.builder().q(i1.getName()).build())
+ .getResults()
+ .size());
+
+ response =
+ searchService.searchInstitutions(
+ InstitutionSearchRequest.builder().q("different").hl(true).build());
+ assertEquals(1, response.getResults().size());
+ assertEquals(1, response.getResults().get(0).getHighlights().size());
+ }
+
+ @Test
+ public void searchCollectionsTest() {
+ assertEquals(
+ 2,
+ searchService
+ .searchCollections(CollectionDescriptorsSearchRequest.builder().build())
+ .getResults()
+ .size());
+
+ assertEquals(
+ 1,
+ searchService
+ .searchCollections(CollectionDescriptorsSearchRequest.builder().q("Asturias").build())
+ .getResults()
+ .size());
+
+ PagingResponse response =
+ searchService.searchCollections(
+ CollectionDescriptorsSearchRequest.builder().q("Asturias").hl(true).build());
+ assertEquals(1, response.getResults().size());
+ assertEquals(1, response.getCount());
+ assertEquals(1, response.getResults().get(0).getHighlights().size());
+ assertTrue(response.getResults().get(0).getDescriptorMatches().isEmpty());
+
+ response =
+ searchService.searchCollections(
+ CollectionDescriptorsSearchRequest.builder().q("aves").build());
+ assertEquals(1, response.getResults().size());
+ assertEquals(1, response.getCount());
+ assertTrue(response.getResults().get(0).getHighlights().isEmpty());
+ assertEquals(2, response.getResults().get(0).getDescriptorMatches().size());
+
+ response =
+ searchService.searchCollections(
+ CollectionDescriptorsSearchRequest.builder().q("aves").hl(true).build());
+ assertEquals(1, response.getResults().size());
+ assertEquals(1, response.getCount());
+ assertEquals(2, response.getResults().get(0).getDescriptorMatches().size());
+ assertEquals(1, response.getResults().get(0).getHighlights().size());
+
+ assertDescriptorSearch(
+ 1,
+ 1,
+ CollectionDescriptorsSearchRequest.builder()
+ .descriptorCountry(Collections.singletonList(Country.UNITED_STATES))
+ .build());
+ assertDescriptorSearch(
+ 1,
+ 2,
+ CollectionDescriptorsSearchRequest.builder()
+ .descriptorCountry(Arrays.asList(Country.PORTUGAL, Country.UNITED_STATES))
+ .build());
+ assertDescriptorSearch(
+ 0,
+ 0,
+ CollectionDescriptorsSearchRequest.builder()
+ .descriptorCountry(Collections.singletonList(Country.AFGHANISTAN))
+ .build());
+ assertDescriptorSearch(
+ 1, 2, CollectionDescriptorsSearchRequest.builder().individualCount("10, 50").build());
+ assertDescriptorSearch(
+ 1,
+ 3,
+ CollectionDescriptorsSearchRequest.builder()
+ .recordedBy(Collections.singletonList("Marcos"))
+ .build());
+ assertDescriptorSearch(
+ 1,
+ 2,
+ CollectionDescriptorsSearchRequest.builder()
+ .typeStatus(Arrays.asList(TypeStatus.COTYPE.name(), TypeStatus.EPITYPE.name()))
+ .build());
+
+ assertDescriptorSearch(
+ 1,
+ null,
+ CollectionDescriptorsSearchRequest.builder()
+ .usageName(Collections.singletonList(NubResourceClientMock.DEFAULT_USAGE.getName()))
+ .build());
+
+ assertDescriptorSearch(
+ 1,
+ 1,
+ CollectionDescriptorsSearchRequest.builder()
+ .descriptorCountry(Collections.singletonList(Country.PORTUGAL))
+ .q("cc2")
+ .build());
+
+ assertDescriptorSearch(
+ 2,
+ null,
+ CollectionDescriptorsSearchRequest.builder()
+ .descriptorCountry(Collections.singletonList(Country.DENMARK))
+ .build());
+
+ PagingResponse first =
+ searchService.searchCollections(
+ CollectionDescriptorsSearchRequest.builder()
+ .descriptorCountry(Collections.singletonList(Country.DENMARK))
+ .limit(1)
+ .build());
+ assertEquals(1, first.getResults().size());
+ PagingResponse second =
+ searchService.searchCollections(
+ CollectionDescriptorsSearchRequest.builder()
+ .descriptorCountry(Collections.singletonList(Country.DENMARK))
+ .offset(1L)
+ .limit(1)
+ .build());
+ assertEquals(1, first.getResults().size());
+ assertNotEquals(first.getResults().get(0).getKey(), second.getResults().get(0).getKey());
+
+ PagingResponse sorted =
+ searchService.searchCollections(
+ CollectionDescriptorsSearchRequest.builder()
+ .sortBy(CollectionsSortField.NUMBER_SPECIMENS)
+ .sortOrder(SortOrder.ASC)
+ .offset(0L)
+ .limit(1)
+ .build());
+ assertEquals(c2.getKey(), sorted.getResults().get(0).getKey());
+ sorted =
+ searchService.searchCollections(
+ CollectionDescriptorsSearchRequest.builder()
+ .sortBy(CollectionsSortField.NUMBER_SPECIMENS)
+ .sortOrder(SortOrder.ASC)
+ .offset(1L)
+ .limit(1)
+ .build());
+ assertEquals(c1.getKey(), sorted.getResults().get(0).getKey());
+ sorted =
+ searchService.searchCollections(
+ CollectionDescriptorsSearchRequest.builder()
+ .sortBy(CollectionsSortField.NUMBER_SPECIMENS)
+ .sortOrder(SortOrder.DESC)
+ .offset(0L)
+ .limit(1)
+ .build());
+ assertEquals(c1.getKey(), sorted.getResults().get(0).getKey());
+
+ PagingResponse result =
+ searchService.searchCollections(
+ CollectionDescriptorsSearchRequest.builder().q("personal").hl(true).build());
+ assertEquals(1, result.getResults().size());
+ assertEquals(c1.getKey(), result.getResults().get(0).getKey());
+ assertEquals(
+ "descriptorGroup.title",
+ result.getResults().get(0).getHighlights().iterator().next().getField());
+ assertTrue(result.getResults().get(0).getDescriptorMatches().isEmpty());
+
+ result =
+ searchService.searchCollections(
+ CollectionDescriptorsSearchRequest.builder().q("unusual").hl(true).build());
+ assertEquals(1, result.getResults().size());
+ assertEquals(c2.getKey(), result.getResults().get(0).getKey());
+ assertEquals(
+ "descriptorGroup.description",
+ result.getResults().get(0).getHighlights().iterator().next().getField());
+ assertTrue(result.getResults().get(0).getDescriptorMatches().isEmpty());
+ }
+
+ private void assertDescriptorSearch(
+ int expectedResults,
+ Integer expectedDescriptors,
+ CollectionDescriptorsSearchRequest searchRequest) {
+ PagingResponse response =
+ searchService.searchCollections(searchRequest);
+ assertEquals(expectedResults, response.getResults().size());
+ assertEquals(expectedResults, response.getCount());
+ if (expectedResults > 0) {
+ assertTrue(response.getResults().stream().noneMatch(v -> v.getDescriptorMatches().isEmpty()));
+ }
+ if (expectedResults == 1 && expectedDescriptors != null) {
+ assertEquals(expectedDescriptors, response.getResults().get(0).getDescriptorMatches().size());
+ }
+ }
}
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/InstitutionServiceIT.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/InstitutionServiceIT.java
index e257af5bee..3623e43cfa 100644
--- a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/InstitutionServiceIT.java
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/InstitutionServiceIT.java
@@ -13,12 +13,20 @@
*/
package org.gbif.registry.ws.it.collections.service;
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.math.BigDecimal;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.UUID;
+import javax.validation.ConstraintViolationException;
+import javax.validation.ValidationException;
import org.gbif.api.model.collections.*;
import org.gbif.api.model.collections.latimercore.ContactDetail;
import org.gbif.api.model.collections.latimercore.MeasurementOrFact;
import org.gbif.api.model.collections.latimercore.OrganisationalUnit;
import org.gbif.api.model.collections.request.InstitutionSearchRequest;
-import org.gbif.api.model.common.paging.PagingRequest;
import org.gbif.api.model.common.paging.PagingResponse;
import org.gbif.api.model.registry.Identifier;
import org.gbif.api.model.registry.Organization;
@@ -39,16 +47,6 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import javax.validation.ConstraintViolationException;
-import javax.validation.ValidationException;
-import java.math.BigDecimal;
-import java.net.URI;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.UUID;
-
-import static org.junit.jupiter.api.Assertions.*;
-
/** Tests the {@link InstitutionService}. */
public class InstitutionServiceIT extends BaseCollectionEntityServiceIT {
@@ -118,30 +116,46 @@ public void listTest() {
sourceMetadata.setSource(Source.IH_IRN);
institution3.setMasterSourceMetadata(sourceMetadata);
UUID key3 = institutionService.create(institution3);
- institutionService.addMasterSourceMetadata(key3,sourceMetadata);
+ institutionService.addMasterSourceMetadata(key3, sourceMetadata);
PagingResponse response =
institutionService.list(
- InstitutionSearchRequest.builder().query("dummy").page(DEFAULT_PAGE).build());
+ (InstitutionSearchRequest.builder().q("dummy").limit(DEFAULT_PAGE.getLimit()))
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(3, response.getResults().size());
- response = institutionService.list(InstitutionSearchRequest.builder().source(Source.IH_IRN).sourceId("test-123").build());
- assertEquals(1,response.getResults().size());
+ response =
+ institutionService.list(
+ InstitutionSearchRequest.builder().source(Source.IH_IRN).sourceId("test-123").build());
+ assertEquals(1, response.getResults().size());
// empty queries are ignored and return all elements
response =
institutionService.list(
- InstitutionSearchRequest.builder().query("").page(DEFAULT_PAGE).build());
+ InstitutionSearchRequest.builder()
+ .q("")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(3, response.getResults().size());
response =
institutionService.list(
- InstitutionSearchRequest.builder().query("city").page(DEFAULT_PAGE).build());
+ InstitutionSearchRequest.builder()
+ .q("city")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(1, response.getResults().size());
assertEquals(key1, response.getResults().get(0).getKey());
response =
institutionService.list(
- InstitutionSearchRequest.builder().query("city2").page(DEFAULT_PAGE).build());
+ InstitutionSearchRequest.builder()
+ .q("city2")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(1, response.getResults().size());
assertEquals(key2, response.getResults().get(0).getKey());
@@ -152,7 +166,8 @@ public void listTest() {
.list(
InstitutionSearchRequest.builder()
.institutionKeys(Arrays.asList(institution1.getKey(), institution2.getKey()))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -162,9 +177,10 @@ public void listTest() {
institutionService
.list(
InstitutionSearchRequest.builder()
- .query(institution1.getCode())
+ .q(institution1.getCode())
.institutionKeys(Arrays.asList(institution1.getKey(), institution2.getKey()))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -173,27 +189,47 @@ public void listTest() {
assertEquals(
1,
institutionService
- .list(InstitutionSearchRequest.builder().code("c1").page(DEFAULT_PAGE).build())
+ .list(
+ InstitutionSearchRequest.builder()
+ .code("c1")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
1,
institutionService
- .list(InstitutionSearchRequest.builder().name("n2").page(DEFAULT_PAGE).build())
+ .list(
+ InstitutionSearchRequest.builder()
+ .name("n2")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
1,
institutionService
.list(
- InstitutionSearchRequest.builder().code("c1").name("n1").page(DEFAULT_PAGE).build())
+ InstitutionSearchRequest.builder()
+ .code("c1")
+ .name("n1")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
0,
institutionService
.list(
- InstitutionSearchRequest.builder().code("c2").name("n1").page(DEFAULT_PAGE).build())
+ InstitutionSearchRequest.builder()
+ .code("c2")
+ .name("n1")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
@@ -201,43 +237,77 @@ public void listTest() {
assertEquals(
3,
institutionService
- .list(InstitutionSearchRequest.builder().query("c").page(DEFAULT_PAGE).build())
+ .list(
+ InstitutionSearchRequest.builder()
+ .q("c")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
2,
institutionService
- .list(InstitutionSearchRequest.builder().query("dum add").page(DEFAULT_PAGE).build())
+ .list(
+ InstitutionSearchRequest.builder()
+ .q("dum add")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
0,
institutionService
- .list(InstitutionSearchRequest.builder().query("<").page(DEFAULT_PAGE).build())
+ .list(
+ InstitutionSearchRequest.builder()
+ .q("<")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
0,
institutionService
- .list(InstitutionSearchRequest.builder().query("\"<\"").page(DEFAULT_PAGE).build())
+ .list(
+ InstitutionSearchRequest.builder()
+ .q("\"<\"")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
3,
institutionService
- .list(InstitutionSearchRequest.builder().page(DEFAULT_PAGE).build())
+ .list(
+ InstitutionSearchRequest.builder()
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
3,
institutionService
- .list(InstitutionSearchRequest.builder().query(" ").page(DEFAULT_PAGE).build())
+ .list(
+ InstitutionSearchRequest.builder()
+ .q(" ")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
2,
institutionService
- .list(InstitutionSearchRequest.builder().active(true).page(DEFAULT_PAGE).build())
+ .list(
+ InstitutionSearchRequest.builder()
+ .active(true)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
@@ -246,7 +316,8 @@ public void listTest() {
.list(
InstitutionSearchRequest.builder()
.type(Collections.singletonList("Herbarium"))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -256,7 +327,8 @@ public void listTest() {
.list(
InstitutionSearchRequest.builder()
.institutionalGovernance(Collections.singletonList("Academic"))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -266,7 +338,8 @@ public void listTest() {
.list(
InstitutionSearchRequest.builder()
.disciplines(Collections.singletonList("Anthropology"))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -276,7 +349,8 @@ public void listTest() {
.list(
InstitutionSearchRequest.builder()
.disciplines(Arrays.asList("Archaeology", "Anthropology"))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -284,19 +358,28 @@ public void listTest() {
// alternative code
response =
institutionService.list(
- InstitutionSearchRequest.builder().alternativeCode("alt").page(DEFAULT_PAGE).build());
+ InstitutionSearchRequest.builder()
+ .alternativeCode("alt")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(1, response.getResults().size());
response =
institutionService.list(
- InstitutionSearchRequest.builder().alternativeCode("foo").page(DEFAULT_PAGE).build());
+ InstitutionSearchRequest.builder()
+ .alternativeCode("foo")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(0, response.getResults().size());
response =
institutionService.list(
InstitutionSearchRequest.builder()
.country(Collections.singletonList(Country.SPAIN))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(1, response.getResults().size());
assertEquals(key2, response.getResults().get(0).getKey());
@@ -304,28 +387,32 @@ public void listTest() {
institutionService.list(
InstitutionSearchRequest.builder()
.country(Collections.singletonList(Country.AFGHANISTAN))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(0, response.getResults().size());
response =
institutionService.list(
InstitutionSearchRequest.builder()
.country(Arrays.asList(Country.SPAIN, Country.AFGHANISTAN))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(1, response.getResults().size());
response =
institutionService.list(
InstitutionSearchRequest.builder()
.country(Arrays.asList(Country.SPAIN, Country.DENMARK))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(2, response.getResults().size());
response =
institutionService.list(
InstitutionSearchRequest.builder()
.gbifRegion(Collections.singletonList(GbifRegion.EUROPE))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(2, response.getResults().size());
response =
@@ -333,18 +420,27 @@ public void listTest() {
InstitutionSearchRequest.builder()
.country(Collections.singletonList(Country.SPAIN))
.gbifRegion(Collections.singletonList(GbifRegion.ASIA))
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build());
assertEquals(0, response.getResults().size());
response =
institutionService.list(
- InstitutionSearchRequest.builder().city("city2").page(DEFAULT_PAGE).build());
+ InstitutionSearchRequest.builder()
+ .city("city2")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(1, response.getResults().size());
assertEquals(key2, response.getResults().get(0).getKey());
response =
institutionService.list(
- InstitutionSearchRequest.builder().city("foo").page(DEFAULT_PAGE).build());
+ InstitutionSearchRequest.builder()
+ .city("foo")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(0, response.getResults().size());
// update address
@@ -355,7 +451,12 @@ public void listTest() {
assertEquals(
1,
institutionService
- .list(InstitutionSearchRequest.builder().query("city3").page(DEFAULT_PAGE).build())
+ .list(
+ InstitutionSearchRequest.builder()
+ .q("city3")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
@@ -365,7 +466,8 @@ public void listTest() {
.list(
InstitutionSearchRequest.builder()
.displayOnNHCPortal(true)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -377,7 +479,8 @@ public void listTest() {
.list(
InstitutionSearchRequest.builder()
.numberSpecimens("100")
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -386,7 +489,11 @@ public void listTest() {
0,
institutionService
.list(
- InstitutionSearchRequest.builder().numberSpecimens("98").page(DEFAULT_PAGE).build())
+ InstitutionSearchRequest.builder()
+ .numberSpecimens("98")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
@@ -396,7 +503,8 @@ public void listTest() {
.list(
InstitutionSearchRequest.builder()
.numberSpecimens("* , 100")
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -407,7 +515,8 @@ public void listTest() {
.list(
InstitutionSearchRequest.builder()
.numberSpecimens("97,300")
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.size());
@@ -418,7 +527,8 @@ public void listTest() {
.list(
InstitutionSearchRequest.builder()
.sortBy(CollectionsSortField.NUMBER_SPECIMENS)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.get(0)
@@ -431,7 +541,8 @@ public void listTest() {
InstitutionSearchRequest.builder()
.sortBy(CollectionsSortField.NUMBER_SPECIMENS)
.sortOrder(SortOrder.DESC)
- .page(DEFAULT_PAGE)
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
.build())
.getResults()
.get(0)
@@ -441,7 +552,12 @@ public void listTest() {
assertEquals(
0,
institutionService
- .list(InstitutionSearchRequest.builder().query("city3").page(DEFAULT_PAGE).build())
+ .list(
+ InstitutionSearchRequest.builder()
+ .q("city3")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
@@ -459,28 +575,48 @@ public void listTest() {
assertEquals(
1,
institutionService
- .list(InstitutionSearchRequest.builder().query("Name1").page(DEFAULT_PAGE).build())
+ .list(
+ InstitutionSearchRequest.builder()
+ .q("Name1")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
1,
institutionService
- .list(InstitutionSearchRequest.builder().query("aa1@aa.com").page(DEFAULT_PAGE).build())
+ .list(
+ InstitutionSearchRequest.builder()
+ .q("aa1@aa.com")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
1,
institutionService
- .list(InstitutionSearchRequest.builder().query("aves").page(DEFAULT_PAGE).build())
+ .list(
+ InstitutionSearchRequest.builder()
+ .q("aves")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
assertEquals(
1,
institutionService
- .list(InstitutionSearchRequest.builder().query("abcde").page(DEFAULT_PAGE).build())
+ .list(
+ InstitutionSearchRequest.builder()
+ .q("abcde")
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build())
.getResults()
.size());
}
@@ -539,7 +675,7 @@ public void listDeletedTest() {
institution4.setName("Institution name4");
UUID key4 = institutionService.create(institution4);
- InstitutionSearchRequest searchRequest = new InstitutionSearchRequest();
+ InstitutionSearchRequest searchRequest = InstitutionSearchRequest.builder().build();
searchRequest.setReplacedBy(key4);
assertEquals(0, institutionService.listDeleted(searchRequest).getResults().size());
institutionService.replace(key3, key4);
@@ -558,23 +694,29 @@ public void listWithoutParametersTest() {
UUID key3 = institutionService.create(institution3);
PagingResponse response =
- institutionService.list(InstitutionSearchRequest.builder().page(DEFAULT_PAGE).build());
+ institutionService.list(
+ InstitutionSearchRequest.builder()
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(3, response.getResults().size());
institutionService.delete(key3);
response =
- institutionService.list(InstitutionSearchRequest.builder().page(DEFAULT_PAGE).build());
+ institutionService.list(
+ InstitutionSearchRequest.builder()
+ .limit(DEFAULT_PAGE.getLimit())
+ .offset(DEFAULT_PAGE.getOffset())
+ .build());
assertEquals(2, response.getResults().size());
response =
- institutionService.list(
- InstitutionSearchRequest.builder().page(new PagingRequest(0L, 1)).build());
+ institutionService.list(InstitutionSearchRequest.builder().limit(1).offset(0L).build());
assertEquals(1, response.getResults().size());
response =
- institutionService.list(
- InstitutionSearchRequest.builder().page(new PagingRequest(0L, 0)).build());
+ institutionService.list(InstitutionSearchRequest.builder().limit(0).offset(0L).build());
assertEquals(0, response.getResults().size());
}
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/descriptors/DescriptorsServiceIT.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/descriptors/DescriptorsServiceIT.java
new file mode 100644
index 0000000000..5279e08ab8
--- /dev/null
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/descriptors/DescriptorsServiceIT.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.gbif.registry.ws.it.collections.service.descriptors;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.*;
+import lombok.SneakyThrows;
+import org.gbif.api.model.collections.Collection;
+import org.gbif.api.model.collections.MasterSourceMetadata;
+import org.gbif.api.model.collections.descriptors.Descriptor;
+import org.gbif.api.model.collections.descriptors.DescriptorGroup;
+import org.gbif.api.model.collections.request.DescriptorGroupSearchRequest;
+import org.gbif.api.model.collections.request.DescriptorSearchRequest;
+import org.gbif.api.model.common.export.ExportFormat;
+import org.gbif.api.model.common.paging.PagingResponse;
+import org.gbif.api.model.registry.MachineTag;
+import org.gbif.api.service.collections.CollectionService;
+import org.gbif.api.service.collections.DescriptorsService;
+import org.gbif.api.util.GrSciCollUtils;
+import org.gbif.api.vocabulary.collections.Source;
+import org.gbif.registry.database.TestCaseDatabaseInitializer;
+import org.gbif.registry.test.mocks.NubResourceClientMock;
+import org.gbif.registry.ws.it.collections.service.BaseServiceIT;
+import org.gbif.ws.client.filter.SimplePrincipalProvider;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.util.StreamUtils;
+
+/** Tests the {@link CollectionService}. */
+public class DescriptorsServiceIT extends BaseServiceIT {
+
+ @RegisterExtension
+ protected TestCaseDatabaseInitializer databaseRule = new TestCaseDatabaseInitializer();
+
+ private final DescriptorsService descriptorsService;
+ private final CollectionService collectionService;
+
+ @Autowired
+ public DescriptorsServiceIT(
+ DescriptorsService descriptorsService,
+ CollectionService collectionService,
+ SimplePrincipalProvider principalProvider) {
+ super(principalProvider);
+ this.descriptorsService = descriptorsService;
+ this.collectionService = collectionService;
+ }
+
+ @Test
+ @SneakyThrows
+ public void descriptorsTest() {
+ Collection collection = new Collection();
+ collection.setCode("c1");
+ collection.setName("n1");
+ collectionService.create(collection);
+
+ Resource descriptorsFile = new ClassPathResource("collections/descriptors.csv");
+ long descriptorGroupKey =
+ descriptorsService.createDescriptorGroup(
+ StreamUtils.copyToByteArray(descriptorsFile.getInputStream()),
+ ExportFormat.TSV,
+ "My descriptor set",
+ "description",
+ collection.getKey());
+ assertTrue(descriptorGroupKey > 0);
+
+ assertEquals(
+ 1,
+ descriptorsService
+ .listDescriptorGroups(
+ collection.getKey(), DescriptorGroupSearchRequest.builder().build())
+ .getResults()
+ .size());
+
+ PagingResponse descriptors =
+ descriptorsService.listDescriptors(DescriptorSearchRequest.builder().build());
+ assertEquals(5, descriptors.getResults().size());
+ assertTrue(descriptors.getResults().stream().allMatch(r -> r.getVerbatim().size() == 4));
+
+ assertEquals(
+ 0,
+ descriptorsService
+ .listDescriptors(
+ DescriptorSearchRequest.builder()
+ .usageName(Collections.singletonList("foo"))
+ .build())
+ .getResults()
+ .size());
+
+ assertEquals(
+ 5,
+ descriptorsService
+ .listDescriptors(
+ DescriptorSearchRequest.builder()
+ .usageKey(
+ Collections.singletonList(NubResourceClientMock.DEFAULT_USAGE.getKey()))
+ .build())
+ .getResults()
+ .size());
+
+ assertEquals(
+ 5,
+ descriptorsService
+ .listDescriptors(
+ DescriptorSearchRequest.builder()
+ .taxonKey(
+ Collections.singletonList(
+ NubResourceClientMock.DEFAULT_HIGHEST_USAGE.getKey()))
+ .build())
+ .getResults()
+ .size());
+
+ Resource descriptorsFile2 = new ClassPathResource("collections/descriptors2.csv");
+ descriptorsService.updateDescriptorGroup(
+ descriptorGroupKey,
+ StreamUtils.copyToByteArray(descriptorsFile2.getInputStream()),
+ ExportFormat.TSV,
+ "My descriptor set",
+ "description");
+
+ descriptors = descriptorsService.listDescriptors(DescriptorSearchRequest.builder().build());
+ assertEquals(4, descriptors.getResults().size());
+ assertTrue(descriptors.getResults().stream().allMatch(r -> r.getVerbatim().size() == 4));
+
+ descriptorsService.deleteDescriptorGroup(descriptorGroupKey);
+ assertEquals(
+ 0,
+ descriptorsService.listDescriptors(DescriptorSearchRequest.builder().build()).getCount());
+ assertEquals(
+ 0,
+ descriptorsService
+ .listDescriptorGroups(
+ collection.getKey(), DescriptorGroupSearchRequest.builder().build())
+ .getCount());
+ }
+
+ @Test
+ @SneakyThrows
+ public void ihDescriptorsTest() {
+ Collection collection = new Collection();
+ collection.setCode("c1");
+ collection.setName("n1");
+ collectionService.create(collection);
+
+ collectionService.addMasterSourceMetadata(
+ collection.getKey(), new MasterSourceMetadata(Source.IH_IRN, "dsfgds"));
+
+ String title = "My descriptor set";
+ String description = "description";
+
+ Resource descriptorsFile = new ClassPathResource("collections/descriptors.csv");
+ long descriptorGroupKey =
+ descriptorsService.createDescriptorGroup(
+ StreamUtils.copyToByteArray(descriptorsFile.getInputStream()),
+ ExportFormat.TSV,
+ title,
+ description,
+ collection.getKey());
+ assertTrue(descriptorGroupKey > 0);
+
+ assertEquals(
+ 1,
+ descriptorsService
+ .listDescriptorGroups(
+ collection.getKey(), DescriptorGroupSearchRequest.builder().build())
+ .getResults()
+ .size());
+
+ PagingResponse descriptors =
+ descriptorsService.listDescriptors(DescriptorSearchRequest.builder().build());
+ assertEquals(5, descriptors.getResults().size());
+
+ collectionService.addMachineTag(
+ collection.getKey(),
+ new MachineTag(
+ GrSciCollUtils.IH_NS,
+ GrSciCollUtils.COLL_SUMMARY_MT,
+ String.valueOf(descriptorGroupKey)));
+
+ descriptorsService.updateDescriptorGroup(
+ descriptorGroupKey,
+ StreamUtils.copyToByteArray(descriptorsFile.getInputStream()),
+ ExportFormat.TSV,
+ "foo",
+ "foo");
+
+ DescriptorGroup updated = descriptorsService.getDescriptorGroup(descriptorGroupKey);
+ assertEquals(title, updated.getTitle());
+ assertEquals(description, updated.getDescription());
+
+ descriptorsService.deleteDescriptorGroup(descriptorGroupKey);
+ assertNull(descriptorsService.getDescriptorGroup(descriptorGroupKey).getDeleted());
+ }
+}
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/suggestions/BaseChangeSuggestionServiceIT.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/suggestions/BaseChangeSuggestionServiceIT.java
index 8ffb6118ad..6ff3fe574d 100644
--- a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/suggestions/BaseChangeSuggestionServiceIT.java
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/collections/service/suggestions/BaseChangeSuggestionServiceIT.java
@@ -457,26 +457,26 @@ public void listTest() {
// When
PagingResponse results =
- changeSuggestionService.list(Status.APPLIED, null, null, null, DEFAULT_PAGE);
+ changeSuggestionService.list(Status.APPLIED, null, null, null, null, DEFAULT_PAGE);
// Then
assertEquals(0, results.getResults().size());
assertEquals(0, results.getCount());
// When
- results = changeSuggestionService.list(null, Type.CREATE, null, null, DEFAULT_PAGE);
+ results = changeSuggestionService.list(null, Type.CREATE, null, null, null, DEFAULT_PAGE);
// Then
assertEquals(1, results.getResults().size());
assertEquals(1, results.getCount());
// When
- results = changeSuggestionService.list(null, null, null, entity2Key, DEFAULT_PAGE);
+ results = changeSuggestionService.list(null, null, null, entity2Key, null, DEFAULT_PAGE);
// Then
assertEquals(1, results.getResults().size());
assertEquals(1, results.getCount());
// When - user with no rights can't see the proposer email
resetSecurityContext("user", UserRole.USER);
- results = changeSuggestionService.list(null, null, null, entity2Key, DEFAULT_PAGE);
+ results = changeSuggestionService.list(null, null, null, entity2Key, null, DEFAULT_PAGE);
// Then
assertTrue(results.getResults().stream().allMatch(v -> v.getProposerEmail() == null));
}
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/persistence/mapper/CollectionMapperIT.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/persistence/mapper/CollectionMapperIT.java
index b5386818da..7a27058fc6 100644
--- a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/persistence/mapper/CollectionMapperIT.java
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/persistence/mapper/CollectionMapperIT.java
@@ -36,7 +36,7 @@
import org.gbif.registry.persistence.mapper.collections.CollectionMapper;
import org.gbif.registry.persistence.mapper.collections.MasterSourceSyncMetadataMapper;
import org.gbif.registry.persistence.mapper.collections.dto.CollectionDto;
-import org.gbif.registry.persistence.mapper.collections.params.CollectionSearchParams;
+import org.gbif.registry.persistence.mapper.collections.params.CollectionListParams;
import org.gbif.registry.search.test.EsManageServer;
import org.gbif.registry.ws.it.BaseItTest;
import org.gbif.ws.client.filter.SimplePrincipalProvider;
@@ -245,44 +245,44 @@ public void listTest() {
Pageable page = PAGE.apply(2, 0L);
List dtos =
- collectionMapper.list(CollectionSearchParams.builder().page(page).build());
+ collectionMapper.list(CollectionListParams.builder().page(page).build());
assertEquals(2, dtos.size());
page = PAGE.apply(5, 0L);
- assertSearch(CollectionSearchParams.builder().sourceId("test-123").source(Source.IH_IRN).build(),1,col5.getKey());
- assertSearch(CollectionSearchParams.builder().page(page).build(), 5);
- assertSearch(CollectionSearchParams.builder().code("c1").page(page).build(), 1);
- assertSearch(CollectionSearchParams.builder().code("C1").page(page).build(), 1);
- assertSearch(CollectionSearchParams.builder().name("n2").page(page).build(), 1);
- assertSearch(CollectionSearchParams.builder().code("c3").name("n3").page(page).build(), 1);
- assertSearch(CollectionSearchParams.builder().code("c1").name("n3").page(page).build(), 0);
+ assertSearch(CollectionListParams.builder().sourceId("test-123").source(Source.IH_IRN).build(),1,col5.getKey());
+ assertSearch(CollectionListParams.builder().page(page).build(), 5);
+ assertSearch(CollectionListParams.builder().code("c1").page(page).build(), 1);
+ assertSearch(CollectionListParams.builder().code("C1").page(page).build(), 1);
+ assertSearch(CollectionListParams.builder().name("n2").page(page).build(), 1);
+ assertSearch(CollectionListParams.builder().code("c3").name("n3").page(page).build(), 1);
+ assertSearch(CollectionListParams.builder().code("c1").name("n3").page(page).build(), 0);
assertSearch(
- CollectionSearchParams.builder().fuzzyName("nime of fourth collection").page(page).build(),
+ CollectionListParams.builder().fuzzyName("nime of fourth collection").page(page).build(),
1);
assertSearch(
- CollectionSearchParams.builder().query("nime of fourth collection").page(page).build(), 0);
+ CollectionListParams.builder().query("nime of fourth collection").page(page).build(), 0);
assertSearch(
- CollectionSearchParams.builder()
+ CollectionListParams.builder()
.countries(Collections.singletonList(Country.DENMARK))
.page(page)
.build(),
1);
assertSearch(
- CollectionSearchParams.builder()
+ CollectionListParams.builder()
.countries(Collections.singletonList(Country.SPAIN))
.page(page)
.build(),
0);
- assertSearch(CollectionSearchParams.builder().city("Odense").page(page).build(), 1);
+ assertSearch(CollectionListParams.builder().city("Odense").page(page).build(), 1);
assertSearch(
- CollectionSearchParams.builder()
+ CollectionListParams.builder()
.city("Copenhagen")
.countries(Collections.singletonList(Country.DENMARK))
.page(page)
.build(),
1);
assertSearch(
- CollectionSearchParams.builder()
+ CollectionListParams.builder()
.city("CPH")
.countries(Collections.singletonList(Country.DENMARK))
.page(page)
@@ -291,24 +291,24 @@ public void listTest() {
// machine tags
assertSearch(
- CollectionSearchParams.builder().machineTagNamespace("dummy").page(page).build(), 0);
+ CollectionListParams.builder().machineTagNamespace("dummy").page(page).build(), 0);
assertSearch(
- CollectionSearchParams.builder().machineTagName(mt.getName()).page(page).build(),
+ CollectionListParams.builder().machineTagName(mt.getName()).page(page).build(),
1,
col1.getKey());
assertSearch(
- CollectionSearchParams.builder().machineTagName(mt.getName()).page(page).build(),
+ CollectionListParams.builder().machineTagName(mt.getName()).page(page).build(),
1,
col1.getKey());
assertSearch(
- CollectionSearchParams.builder().machineTagValue(mt.getValue()).page(page).build(),
+ CollectionListParams.builder().machineTagValue(mt.getValue()).page(page).build(),
1,
col1.getKey());
assertSearch(
- CollectionSearchParams.builder()
+ CollectionListParams.builder()
.machineTagName(mt.getName())
.machineTagName(mt.getName())
.machineTagValue(mt.getValue())
@@ -318,9 +318,9 @@ public void listTest() {
col1.getKey());
// identifiers
- assertSearch(CollectionSearchParams.builder().identifier("dummy").page(page).build(), 0);
+ assertSearch(CollectionListParams.builder().identifier("dummy").page(page).build(), 0);
assertSearch(
- CollectionSearchParams.builder()
+ CollectionListParams.builder()
.machineTagName(mt.getName())
.machineTagName(mt.getName())
.machineTagValue(mt.getValue())
@@ -330,17 +330,17 @@ public void listTest() {
col1.getKey());
assertSearch(
- CollectionSearchParams.builder().identifierType(identifier.getType()).page(page).build(),
+ CollectionListParams.builder().identifierType(identifier.getType()).page(page).build(),
1,
col2.getKey());
assertSearch(
- CollectionSearchParams.builder().identifier(identifier.getIdentifier()).page(page).build(),
+ CollectionListParams.builder().identifier(identifier.getIdentifier()).page(page).build(),
1,
col2.getKey());
assertSearch(
- CollectionSearchParams.builder()
+ CollectionListParams.builder()
.identifierType(identifier.getType())
.identifier(identifier.getIdentifier())
.page(page)
@@ -349,12 +349,12 @@ public void listTest() {
col2.getKey());
assertSearch(
- CollectionSearchParams.builder().masterSourceType(MasterSourceType.IH).page(page).build(),
+ CollectionListParams.builder().masterSourceType(MasterSourceType.IH).page(page).build(),
1,
col1.getKey());
assertSearch(
- CollectionSearchParams.builder()
+ CollectionListParams.builder()
.masterSourceType(MasterSourceType.GBIF_REGISTRY)
.page(page)
.build(),
@@ -362,7 +362,7 @@ public void listTest() {
col2.getKey());
assertSearch(
- CollectionSearchParams.builder()
+ CollectionListParams.builder()
.masterSourceType(MasterSourceType.GRSCICOLL)
.page(page)
.build(),
@@ -396,16 +396,16 @@ public void searchTest() {
Pageable page = PAGE.apply(5, 0L);
assertSearch(
- CollectionSearchParams.builder().query("c1 n1").page(page).build(), 1, col1.getKey());
+ CollectionListParams.builder().query("c1 n1").page(page).build(), 1, col1.getKey());
- assertSearch(CollectionSearchParams.builder().query("c2 c1").page(page).build(), 0);
- assertSearch(CollectionSearchParams.builder().query("c3").page(page).build(), 0);
- assertSearch(CollectionSearchParams.builder().query("n1").page(page).build(), 2);
- assertSearch(CollectionSearchParams.builder().query("insecta").page(page).build(), 1);
- assertSearch(CollectionSearchParams.builder().query("Hymenoptera").page(page).build(), 1);
+ assertSearch(CollectionListParams.builder().query("c2 c1").page(page).build(), 0);
+ assertSearch(CollectionListParams.builder().query("c3").page(page).build(), 0);
+ assertSearch(CollectionListParams.builder().query("n1").page(page).build(), 2);
+ assertSearch(CollectionListParams.builder().query("insecta").page(page).build(), 1);
+ assertSearch(CollectionListParams.builder().query("Hymenoptera").page(page).build(), 1);
assertSearch(
- CollectionSearchParams.builder().query("dummy address fo ").page(page).build(),
+ CollectionListParams.builder().query("dummy address fo ").page(page).build(),
1,
col1.getKey());
@@ -428,13 +428,13 @@ public void searchTest() {
assertNotNull(contact1.getModified());
collectionMapper.addContactPerson(col1.getKey(), contact1.getKey());
- assertSearch(CollectionSearchParams.builder().query("Name1").page(page).build(), 1);
- assertSearch(CollectionSearchParams.builder().query("Name0").page(page).build(), 0);
- assertSearch(CollectionSearchParams.builder().query("Surname1").page(page).build(), 1);
- assertSearch(CollectionSearchParams.builder().query("aa1@aa.com").page(page).build(), 1);
- assertSearch(CollectionSearchParams.builder().query("aves").page(page).build(), 1);
- assertSearch(CollectionSearchParams.builder().query("12345").page(page).build(), 1);
- assertSearch(CollectionSearchParams.builder().query("abcde").page(page).build(), 1);
+ assertSearch(CollectionListParams.builder().query("Name1").page(page).build(), 1);
+ assertSearch(CollectionListParams.builder().query("Name0").page(page).build(), 0);
+ assertSearch(CollectionListParams.builder().query("Surname1").page(page).build(), 1);
+ assertSearch(CollectionListParams.builder().query("aa1@aa.com").page(page).build(), 1);
+ assertSearch(CollectionListParams.builder().query("aves").page(page).build(), 1);
+ assertSearch(CollectionListParams.builder().query("12345").page(page).build(), 1);
+ assertSearch(CollectionListParams.builder().query("abcde").page(page).build(), 1);
}
@Test
@@ -458,7 +458,7 @@ public void alternativeCodesTest() {
collectionMapper.create(coll2);
Pageable page = PAGE.apply(1, 0L);
- CollectionSearchParams params = CollectionSearchParams.builder().query("c1").page(page).build();
+ CollectionListParams params = CollectionListParams.builder().query("c1").page(page).build();
List dtos = collectionMapper.list(params);
long count = collectionMapper.count(params);
assertEquals(1, dtos.size());
@@ -466,10 +466,10 @@ public void alternativeCodesTest() {
assertEquals(2, count);
page = PAGE.apply(2, 0L);
- assertSearch(CollectionSearchParams.builder().query("c1").page(page).build(), 2);
+ assertSearch(CollectionListParams.builder().query("c1").page(page).build(), 2);
page = PAGE.apply(1, 0L);
- params = CollectionSearchParams.builder().query("c2").page(page).build();
+ params = CollectionListParams.builder().query("c2").page(page).build();
dtos = collectionMapper.list(params);
count = collectionMapper.count(params);
assertEquals(1, dtos.size());
@@ -477,15 +477,15 @@ public void alternativeCodesTest() {
assertEquals(2, count);
page = PAGE.apply(2, 0L);
- assertSearch(CollectionSearchParams.builder().query("c2").page(page).build(), 2);
+ assertSearch(CollectionListParams.builder().query("c2").page(page).build(), 2);
assertSearch(
- CollectionSearchParams.builder().alternativeCode("c1").page(page).build(),
+ CollectionListParams.builder().alternativeCode("c1").page(page).build(),
1,
coll2.getKey());
}
- private List assertSearch(CollectionSearchParams params, int expected) {
+ private List assertSearch(CollectionListParams params, int expected) {
List dtos = collectionMapper.list(params);
long count = collectionMapper.count(params);
assertEquals(expected, count);
@@ -493,7 +493,7 @@ private List assertSearch(CollectionSearchParams params, int expe
return dtos;
}
- private void assertSearch(CollectionSearchParams params, int expected, UUID expectedKey) {
+ private void assertSearch(CollectionListParams params, int expected, UUID expectedKey) {
List dtos = assertSearch(params, expected);
assertEquals(expectedKey, dtos.get(0).getCollection().getKey());
}
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/persistence/mapper/CollectionsSearchMapperIT.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/persistence/mapper/CollectionsSearchMapperIT.java
new file mode 100644
index 0000000000..3f7e0c0881
--- /dev/null
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/persistence/mapper/CollectionsSearchMapperIT.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.gbif.registry.ws.it.persistence.mapper;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import org.gbif.api.model.collections.Address;
+import org.gbif.api.model.collections.AlternativeCode;
+import org.gbif.api.model.collections.Collection;
+import org.gbif.api.model.collections.descriptors.DescriptorGroup;
+import org.gbif.api.vocabulary.Country;
+import org.gbif.api.vocabulary.License;
+import org.gbif.registry.database.TestCaseDatabaseInitializer;
+import org.gbif.registry.persistence.mapper.collections.AddressMapper;
+import org.gbif.registry.persistence.mapper.collections.CollectionMapper;
+import org.gbif.registry.persistence.mapper.collections.CollectionsSearchMapper;
+import org.gbif.registry.persistence.mapper.collections.DescriptorsMapper;
+import org.gbif.registry.persistence.mapper.collections.dto.CollectionSearchDto;
+import org.gbif.registry.persistence.mapper.collections.dto.DescriptorDto;
+import org.gbif.registry.persistence.mapper.collections.params.DescriptorsParams;
+import org.gbif.registry.search.test.EsManageServer;
+import org.gbif.registry.ws.it.BaseItTest;
+import org.gbif.ws.client.filter.SimplePrincipalProvider;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class CollectionsSearchMapperIT extends BaseItTest {
+
+ @RegisterExtension
+ protected TestCaseDatabaseInitializer databaseRule =
+ new TestCaseDatabaseInitializer("collection");
+
+ private CollectionMapper collectionMapper;
+ private AddressMapper addressMapper;
+ private DescriptorsMapper descriptorsMapper;
+ private CollectionsSearchMapper collectionsSearchMapper;
+
+ @Autowired
+ public CollectionsSearchMapperIT(
+ CollectionMapper collectionMapper,
+ AddressMapper addressMapper,
+ DescriptorsMapper descriptorsMapper,
+ CollectionsSearchMapper collectionsSearchMapper,
+ SimplePrincipalProvider principalProvider,
+ EsManageServer esServer) {
+ super(principalProvider, esServer);
+ this.collectionMapper = collectionMapper;
+ this.addressMapper = addressMapper;
+ this.descriptorsMapper = descriptorsMapper;
+ this.collectionsSearchMapper = collectionsSearchMapper;
+ }
+
+ @Test
+ public void searchTest() {
+ UUID collectionKey = UUID.randomUUID();
+
+ Collection collection = new Collection();
+ collection.setKey(collectionKey);
+ collection.setAccessionStatus("Institutional");
+ collection.setCode("CODE");
+ collection.setName("NAME");
+ collection.setCreatedBy("test");
+ collection.setModifiedBy("test");
+ collection.setEmail(Collections.singletonList("test@test.com"));
+ collection.setPhone(Collections.singletonList("1234"));
+ collection.setNumberSpecimens(12);
+ collection.setTaxonomicCoverage("taxonomic coverage");
+ collection.setGeographicCoverage("geography");
+ collection.setNotes("notes for testing");
+ collection.setIncorporatedCollections(Arrays.asList("col1", "col2"));
+ collection.setImportantCollectors(Arrays.asList("collector 1", "collector 2"));
+ collection.setCollectionSummary(Collections.singletonMap("collectionKey", 0));
+ collection.setAlternativeCodes(
+ Collections.singletonList(new AlternativeCode("CODE2", "another code")));
+ collection.setDivision("division");
+ collection.setDepartment("department");
+ collection.setDisplayOnNHCPortal(true);
+ collection.setFeaturedImageUrl(URI.create("http://test.com"));
+ collection.setFeaturedImageLicense(License.CC0_1_0);
+ collection.setTemporalCoverage("temporal coverage");
+ collection.setFeaturedImageAttribution("dummy image attribution");
+
+ List preservationTypes = new ArrayList<>();
+ preservationTypes.add("StorageControlledAtmosphere");
+ preservationTypes.add("SampleCryopreserved");
+ collection.setPreservationTypes(preservationTypes);
+
+ Address address = new Address();
+ address.setAddress("dummy address");
+ address.setCountry(Country.SPAIN);
+ address.setCity("Oviedo");
+ addressMapper.create(address);
+ assertNotNull(address.getKey());
+ collection.setAddress(address);
+
+ Address mailingAddress = new Address();
+ mailingAddress.setAddress("dummy mailing address");
+ mailingAddress.setCountry(Country.SPAIN);
+ mailingAddress.setCity("Oviedo");
+ addressMapper.create(mailingAddress);
+ assertNotNull(mailingAddress.getKey());
+ collection.setMailingAddress(mailingAddress);
+
+ collectionMapper.create(collection);
+
+ DescriptorGroup DescriptorGroup = new DescriptorGroup();
+ DescriptorGroup.setCollectionKey(collectionKey);
+ DescriptorGroup.setTitle("title");
+ DescriptorGroup.setCreatedBy("test");
+ DescriptorGroup.setModifiedBy("test");
+ descriptorsMapper.createDescriptorGroup(DescriptorGroup);
+
+ DescriptorDto descriptorDto = new DescriptorDto();
+ descriptorDto.setDescriptorGroupKey(DescriptorGroup.getKey());
+ descriptorDto.setUsageName("aves");
+ descriptorDto.setCountry(Country.SPAIN);
+ descriptorsMapper.createDescriptor(descriptorDto);
+
+ List dtos =
+ collectionsSearchMapper.searchCollections(
+ DescriptorsParams.builder().query("aves").build());
+ assertEquals(1, dtos.size());
+ assertEquals(Country.SPAIN, dtos.get(0).getCountry());
+ assertEquals(Country.SPAIN, dtos.get(0).getMailingCountry());
+ assertEquals("Oviedo", dtos.get(0).getCity());
+ assertEquals("Oviedo", dtos.get(0).getMailingCity());
+
+ dtos =
+ collectionsSearchMapper.searchCollections(
+ DescriptorsParams.builder().query("division").build());
+ assertEquals(1, dtos.size());
+ assertEquals(0, dtos.get(0).getQueryDescriptorRank());
+ assertTrue(dtos.get(0).getQueryRank() > 0);
+
+ dtos =
+ collectionsSearchMapper.searchCollections(
+ DescriptorsParams.builder().query("aves").build());
+ assertEquals(1, dtos.size());
+ assertEquals(0, dtos.get(0).getQueryRank());
+ assertTrue(dtos.get(0).getQueryDescriptorRank() > 0);
+
+ dtos =
+ collectionsSearchMapper.searchCollections(
+ DescriptorsParams.builder().usageName(Collections.singletonList("aves")).build());
+ assertEquals(1, dtos.size());
+ assertNotNull(dtos.get(0).getDescriptorKey());
+ }
+}
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/persistence/mapper/DescriptorsMapperIT.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/persistence/mapper/DescriptorsMapperIT.java
new file mode 100644
index 0000000000..fc8482468c
--- /dev/null
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/persistence/mapper/DescriptorsMapperIT.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.gbif.registry.ws.it.persistence.mapper;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.UUID;
+import org.gbif.api.model.collections.Collection;
+import org.gbif.api.model.collections.descriptors.DescriptorGroup;
+import org.gbif.api.v2.RankedName;
+import org.gbif.api.vocabulary.Country;
+import org.gbif.api.vocabulary.Rank;
+import org.gbif.api.vocabulary.TypeStatus;
+import org.gbif.registry.database.TestCaseDatabaseInitializer;
+import org.gbif.registry.persistence.mapper.collections.CollectionMapper;
+import org.gbif.registry.persistence.mapper.collections.DescriptorsMapper;
+import org.gbif.registry.persistence.mapper.collections.dto.DescriptorDto;
+import org.gbif.registry.persistence.mapper.collections.params.DescriptorGroupParams;
+import org.gbif.registry.persistence.mapper.collections.params.DescriptorParams;
+import org.gbif.registry.search.test.EsManageServer;
+import org.gbif.registry.ws.it.BaseItTest;
+import org.gbif.ws.client.filter.SimplePrincipalProvider;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DescriptorsMapperIT extends BaseItTest {
+
+ @RegisterExtension
+ protected TestCaseDatabaseInitializer databaseRule =
+ new TestCaseDatabaseInitializer(
+ "collection",
+ "collection_descriptor_group",
+ "collection_descriptor",
+ "collection_descriptor_verbatim");
+
+ private final DescriptorsMapper descriptorsMapper;
+ private final CollectionMapper collectionMapper;
+
+ @Autowired
+ public DescriptorsMapperIT(
+ DescriptorsMapper descriptorsMapper,
+ CollectionMapper collectionMapper,
+ SimplePrincipalProvider principalProvider,
+ EsManageServer esServer) {
+ super(principalProvider, esServer);
+ this.descriptorsMapper = descriptorsMapper;
+ this.collectionMapper = collectionMapper;
+ }
+
+ @Test
+ public void crudTest() {
+ Collection collection = new Collection();
+ collection.setCode("code");
+ collection.setName("name");
+ collection.setKey(UUID.randomUUID());
+ collection.setCreatedBy("test");
+ collection.setModifiedBy("test");
+ collectionMapper.create(collection);
+ assertNotNull(collection.getKey());
+
+ DescriptorGroup descriptorGroup = new DescriptorGroup();
+ descriptorGroup.setTitle("title");
+ descriptorGroup.setDescription("description");
+ descriptorGroup.setCreatedBy("user");
+ descriptorGroup.setModifiedBy("user");
+ descriptorGroup.setCollectionKey(collection.getKey());
+ descriptorsMapper.createDescriptorGroup(descriptorGroup);
+ assertTrue(descriptorGroup.getKey() > 0);
+
+ DescriptorGroup created = descriptorsMapper.getDescriptorGroup(descriptorGroup.getKey());
+ assertTrue(descriptorGroup.lenientEquals(created));
+
+ created.setTitle("title2");
+ descriptorsMapper.updateDescriptorGroup(created);
+
+ DescriptorGroup updated = descriptorsMapper.getDescriptorGroup(descriptorGroup.getKey());
+ assertTrue(updated.lenientEquals(created));
+
+ assertEquals(
+ 1,
+ descriptorsMapper
+ .listDescriptorGroups(
+ DescriptorGroupParams.builder().collectionKey(collection.getKey()).build())
+ .size());
+
+ DescriptorDto descriptorDto = new DescriptorDto();
+ descriptorDto.setDescriptorGroupKey(descriptorGroup.getKey());
+ descriptorDto.setCountry(Country.DENMARK);
+ descriptorDto.setDiscipline("discipline");
+ descriptorDto.setIssues(Arrays.asList("i1", "i2"));
+ descriptorDto.setTypeStatus(Collections.singletonList(TypeStatus.ALLOLECTOTYPE.name()));
+ descriptorDto.setUsageRank(Rank.ABERRATION);
+ descriptorDto.setUsageName("usage");
+ descriptorDto.setUsageKey(5);
+
+ descriptorDto.setTaxonClassification(
+ Arrays.asList(
+ new RankedName(1, "Kingdom", Rank.KINGDOM), new RankedName(3, "Phylum", Rank.PHYLUM)));
+ descriptorsMapper.createDescriptor(descriptorDto);
+ assertTrue(descriptorDto.getKey() > 0);
+
+ descriptorsMapper.createVerbatim(descriptorDto.getKey(), "f1", "v1");
+ descriptorsMapper.createVerbatim(descriptorDto.getKey(), "f2", "v2");
+
+ DescriptorDto createdDescriptor = descriptorsMapper.getDescriptor(descriptorDto.getKey());
+ assertEquals(2, createdDescriptor.getIssues().size());
+ assertEquals(1, createdDescriptor.getTypeStatus().size());
+ assertEquals(Country.DENMARK, createdDescriptor.getCountry());
+ assertEquals(2, createdDescriptor.getVerbatim().size());
+ assertEquals(Rank.ABERRATION, createdDescriptor.getUsageRank());
+ assertEquals(2, createdDescriptor.getTaxonClassification().size());
+
+ assertEquals(2, descriptorsMapper.getVerbatimNames(descriptorGroup.getKey()).size());
+
+ assertEquals(
+ 1,
+ descriptorsMapper
+ .listDescriptors(
+ DescriptorParams.builder().descriptorGroupKey(descriptorGroup.getKey()).build())
+ .size());
+
+ assertEquals(
+ 1,
+ descriptorsMapper
+ .listDescriptors(
+ DescriptorParams.builder().usageKey(Collections.singletonList(5)).build())
+ .size());
+
+ assertEquals(
+ 1,
+ descriptorsMapper
+ .listDescriptors(
+ DescriptorParams.builder()
+ .usageRank(Collections.singletonList(Rank.ABERRATION))
+ .build())
+ .size());
+
+ descriptorsMapper.deleteDescriptorGroup(descriptorGroup.getKey());
+ assertTrue(
+ descriptorsMapper
+ .listDescriptorGroups(
+ DescriptorGroupParams.builder().collectionKey(collection.getKey()).build())
+ .isEmpty());
+
+ assertEquals(
+ 1,
+ descriptorsMapper
+ .listDescriptorGroups(DescriptorGroupParams.builder().deleted(true).build())
+ .size());
+
+ descriptorsMapper.deleteDescriptors(descriptorGroup.getKey());
+
+ assertEquals(
+ 0,
+ descriptorsMapper
+ .listDescriptors(
+ DescriptorParams.builder().descriptorGroupKey(descriptorGroup.getKey()).build())
+ .size());
+ }
+}
diff --git a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/persistence/mapper/InstitutionMapperIT.java b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/persistence/mapper/InstitutionMapperIT.java
index 04bfd1d215..f3b7fa759f 100644
--- a/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/persistence/mapper/InstitutionMapperIT.java
+++ b/registry-integration-tests/src/test/java/org/gbif/registry/ws/it/persistence/mapper/InstitutionMapperIT.java
@@ -35,7 +35,7 @@
import org.gbif.registry.persistence.mapper.collections.CollectionContactMapper;
import org.gbif.registry.persistence.mapper.collections.InstitutionMapper;
import org.gbif.registry.persistence.mapper.collections.MasterSourceSyncMetadataMapper;
-import org.gbif.registry.persistence.mapper.collections.params.InstitutionSearchParams;
+import org.gbif.registry.persistence.mapper.collections.params.InstitutionListParams;
import org.gbif.registry.search.test.EsManageServer;
import org.gbif.registry.ws.it.BaseItTest;
import org.gbif.ws.client.filter.SimplePrincipalProvider;
@@ -226,40 +226,40 @@ public void listTest() {
Pageable page = PAGE.apply(5, 0L);
- assertSearch(InstitutionSearchParams.builder().sourceId("test-123").source(Source.IH_IRN).build(),1,inst4.getKey());
- assertSearch(InstitutionSearchParams.builder().page(page).build(), 4);
- assertSearch(InstitutionSearchParams.builder().code("i1").page(page).build(), 1);
- assertSearch(InstitutionSearchParams.builder().code("I1").page(page).build(), 1);
- assertSearch(InstitutionSearchParams.builder().name("n2").page(page).build(), 1);
- assertSearch(InstitutionSearchParams.builder().code("i2").name("n2").page(page).build(), 1);
- assertSearch(InstitutionSearchParams.builder().code("i1").name("n2").page(page).build(), 0);
+ assertSearch(InstitutionListParams.builder().sourceId("test-123").source(Source.IH_IRN).build(),1,inst4.getKey());
+ assertSearch(InstitutionListParams.builder().page(page).build(), 4);
+ assertSearch(InstitutionListParams.builder().code("i1").page(page).build(), 1);
+ assertSearch(InstitutionListParams.builder().code("I1").page(page).build(), 1);
+ assertSearch(InstitutionListParams.builder().name("n2").page(page).build(), 1);
+ assertSearch(InstitutionListParams.builder().code("i2").name("n2").page(page).build(), 1);
+ assertSearch(InstitutionListParams.builder().code("i1").name("n2").page(page).build(), 0);
assertSearch(
- InstitutionSearchParams.builder().fuzzyName("nime of third institution").page(page).build(),
+ InstitutionListParams.builder().fuzzyName("nime of third institution").page(page).build(),
1);
assertSearch(
- InstitutionSearchParams.builder().query("nime of third institution").page(page).build(), 0);
+ InstitutionListParams.builder().query("nime of third institution").page(page).build(), 0);
assertSearch(
- InstitutionSearchParams.builder()
+ InstitutionListParams.builder()
.countries(Collections.singletonList(Country.DENMARK))
.page(page)
.build(),
1);
assertSearch(
- InstitutionSearchParams.builder()
+ InstitutionListParams.builder()
.countries(Collections.singletonList(Country.SPAIN))
.page(page)
.build(),
0);
- assertSearch(InstitutionSearchParams.builder().city("Odense").page(page).build(), 1);
+ assertSearch(InstitutionListParams.builder().city("Odense").page(page).build(), 1);
assertSearch(
- InstitutionSearchParams.builder()
+ InstitutionListParams.builder()
.city("Copenhagen")
.countries(Collections.singletonList(Country.DENMARK))
.page(page)
.build(),
1);
assertSearch(
- InstitutionSearchParams.builder()
+ InstitutionListParams.builder()
.city("CPH")
.countries(Collections.singletonList(Country.DENMARK))
.page(page)
@@ -268,24 +268,24 @@ public void listTest() {
// machine tags
assertSearch(
- InstitutionSearchParams.builder().machineTagNamespace("dummy").page(page).build(), 0);
+ InstitutionListParams.builder().machineTagNamespace("dummy").page(page).build(), 0);
assertSearch(
- InstitutionSearchParams.builder().machineTagName(mt.getName()).page(page).build(),
+ InstitutionListParams.builder().machineTagName(mt.getName()).page(page).build(),
1,
inst1.getKey());
assertSearch(
- InstitutionSearchParams.builder().machineTagName(mt.getName()).page(page).build(),
+ InstitutionListParams.builder().machineTagName(mt.getName()).page(page).build(),
1,
inst1.getKey());
assertSearch(
- InstitutionSearchParams.builder().machineTagValue(mt.getValue()).page(page).build(),
+ InstitutionListParams.builder().machineTagValue(mt.getValue()).page(page).build(),
1,
inst1.getKey());
assertSearch(
- InstitutionSearchParams.builder()
+ InstitutionListParams.builder()
.machineTagName(mt.getName())
.machineTagName(mt.getName())
.machineTagValue(mt.getValue())
@@ -295,9 +295,9 @@ public void listTest() {
inst1.getKey());
// identifiers
- assertSearch(InstitutionSearchParams.builder().identifier("dummy").page(page).build(), 0);
+ assertSearch(InstitutionListParams.builder().identifier("dummy").page(page).build(), 0);
assertSearch(
- InstitutionSearchParams.builder()
+ InstitutionListParams.builder()
.machineTagName(mt.getName())
.machineTagName(mt.getName())
.machineTagValue(mt.getValue())
@@ -307,17 +307,17 @@ public void listTest() {
inst1.getKey());
assertSearch(
- InstitutionSearchParams.builder().identifierType(identifier.getType()).page(page).build(),
+ InstitutionListParams.builder().identifierType(identifier.getType()).page(page).build(),
1,
inst2.getKey());
assertSearch(
- InstitutionSearchParams.builder().identifier(identifier.getIdentifier()).page(page).build(),
+ InstitutionListParams.builder().identifier(identifier.getIdentifier()).page(page).build(),
1,
inst2.getKey());
assertSearch(
- InstitutionSearchParams.builder()
+ InstitutionListParams.builder()
.identifierType(identifier.getType())
.identifier(identifier.getIdentifier())
.page(page)
@@ -326,12 +326,12 @@ public void listTest() {
inst2.getKey());
assertSearch(
- InstitutionSearchParams.builder().masterSourceType(MasterSourceType.IH).page(page).build(),
+ InstitutionListParams.builder().masterSourceType(MasterSourceType.IH).page(page).build(),
1,
inst1.getKey());
assertSearch(
- InstitutionSearchParams.builder()
+ InstitutionListParams.builder()
.masterSourceType(MasterSourceType.GBIF_REGISTRY)
.page(page)
.build(),
@@ -339,7 +339,7 @@ public void listTest() {
inst2.getKey());
assertSearch(
- InstitutionSearchParams.builder()
+ InstitutionListParams.builder()
.masterSourceType(MasterSourceType.GRSCICOLL)
.page(page)
.build(),
@@ -373,12 +373,12 @@ public void searchTest() {
Pageable page = PAGE.apply(5, 0L);
assertSearch(
- InstitutionSearchParams.builder().query("i1 n1").page(page).build(), 1, inst1.getKey());
- assertSearch(InstitutionSearchParams.builder().query("i2 i1").page(page).build(), 0);
- assertSearch(InstitutionSearchParams.builder().query("i3").page(page).build(), 0);
- assertSearch(InstitutionSearchParams.builder().query("n1").page(page).build(), 2);
+ InstitutionListParams.builder().query("i1 n1").page(page).build(), 1, inst1.getKey());
+ assertSearch(InstitutionListParams.builder().query("i2 i1").page(page).build(), 0);
+ assertSearch(InstitutionListParams.builder().query("i3").page(page).build(), 0);
+ assertSearch(InstitutionListParams.builder().query("n1").page(page).build(), 2);
assertSearch(
- InstitutionSearchParams.builder().query("dummy address fo ").page(page).build(),
+ InstitutionListParams.builder().query("dummy address fo ").page(page).build(),
1,
inst1.getKey());
@@ -401,13 +401,13 @@ public void searchTest() {
assertNotNull(contact1.getModified());
institutionMapper.addContactPerson(inst1.getKey(), contact1.getKey());
- assertSearch(InstitutionSearchParams.builder().query("Name1").page(page).build(), 1);
- assertSearch(InstitutionSearchParams.builder().query("Name0").page(page).build(), 0);
- assertSearch(InstitutionSearchParams.builder().query("Surname1").page(page).build(), 1);
- assertSearch(InstitutionSearchParams.builder().query("aa1@aa.com").page(page).build(), 1);
- assertSearch(InstitutionSearchParams.builder().query("aves").page(page).build(), 1);
- assertSearch(InstitutionSearchParams.builder().query("12345").page(page).build(), 1);
- assertSearch(InstitutionSearchParams.builder().query("abcde").page(page).build(), 1);
+ assertSearch(InstitutionListParams.builder().query("Name1").page(page).build(), 1);
+ assertSearch(InstitutionListParams.builder().query("Name0").page(page).build(), 0);
+ assertSearch(InstitutionListParams.builder().query("Surname1").page(page).build(), 1);
+ assertSearch(InstitutionListParams.builder().query("aa1@aa.com").page(page).build(), 1);
+ assertSearch(InstitutionListParams.builder().query("aves").page(page).build(), 1);
+ assertSearch(InstitutionListParams.builder().query("12345").page(page).build(), 1);
+ assertSearch(InstitutionListParams.builder().query("abcde").page(page).build(), 1);
}
@Test
@@ -432,10 +432,10 @@ public void alternativeCodesTest() {
Pageable page = PAGE.apply(1, 0L);
assertSearch(
- InstitutionSearchParams.builder().query("i1 n1").page(page).build(), 1, inst1.getKey());
+ InstitutionListParams.builder().query("i1 n1").page(page).build(), 1, inst1.getKey());
- InstitutionSearchParams params =
- InstitutionSearchParams.builder().query("i1").page(page).build();
+ InstitutionListParams params =
+ InstitutionListParams.builder().query("i1").page(page).build();
List institutions = institutionMapper.list(params);
long count = institutionMapper.count(params);
assertEquals(1, institutions.size());
@@ -444,7 +444,7 @@ public void alternativeCodesTest() {
// there are 2 insts with i1
assertEquals(2, count);
- params = InstitutionSearchParams.builder().query("i2").page(page).build();
+ params = InstitutionListParams.builder().query("i2").page(page).build();
institutions = institutionMapper.list(params);
count = institutionMapper.count(params);
assertEquals(1, institutions.size());
@@ -454,12 +454,12 @@ public void alternativeCodesTest() {
assertEquals(2, count);
assertSearch(
- InstitutionSearchParams.builder().alternativeCode("i1").page(page).page(page).build(),
+ InstitutionListParams.builder().alternativeCode("i1").page(page).page(page).build(),
1,
inst2.getKey());
}
- private List assertSearch(InstitutionSearchParams params, int expected) {
+ private List assertSearch(InstitutionListParams params, int expected) {
List res = institutionMapper.list(params);
long count = institutionMapper.count(params);
assertEquals(expected, count);
@@ -467,7 +467,7 @@ private List assertSearch(InstitutionSearchParams params, int expec
return res;
}
- private void assertSearch(InstitutionSearchParams params, int expected, UUID expectedKey) {
+ private void assertSearch(InstitutionListParams params, int expected, UUID expectedKey) {
List res = assertSearch(params, expected);
assertEquals(expectedKey, res.get(0).getKey());
}
diff --git a/registry-integration-tests/src/test/resources/collections/descriptors.csv b/registry-integration-tests/src/test/resources/collections/descriptors.csv
new file mode 100644
index 0000000000..b4ad9e8512
--- /dev/null
+++ b/registry-integration-tests/src/test/resources/collections/descriptors.csv
@@ -0,0 +1,6 @@
+dwc:scientificName Num. of Specimens Num. Databased Num. Imaged
+Algae 244262 244000 45660
+Bryophytes 5476 8821 2085
+Fungi/Lichens 117358 106427 16269
+Pteridophytes 269359 280000 266443
+Seed Plants 2202411 2242328 1407799
\ No newline at end of file
diff --git a/registry-integration-tests/src/test/resources/collections/descriptors2.csv b/registry-integration-tests/src/test/resources/collections/descriptors2.csv
new file mode 100644
index 0000000000..4d37a7f405
--- /dev/null
+++ b/registry-integration-tests/src/test/resources/collections/descriptors2.csv
@@ -0,0 +1,5 @@
+dwc:scientificName Num. of Specimens Num. Databased dwc:country
+Aves 244262 244000 DK
+Bryophytes 5476 8821
+Fungi/Lichens 117358 106427
+Aves 269359 280000
diff --git a/registry-integration-tests/src/test/resources/collections/descriptors3.csv b/registry-integration-tests/src/test/resources/collections/descriptors3.csv
new file mode 100644
index 0000000000..5b51293e19
--- /dev/null
+++ b/registry-integration-tests/src/test/resources/collections/descriptors3.csv
@@ -0,0 +1,5 @@
+dwc:country dwc:individualCount dwc:recordedBy dwc:typeStatus
+DK 124 Tim|Marcos COTYPE
+DK 15 Tim|Marcos COTYPE|EPITYPE
+PT 56 Tim|Marcos|Marie
+US 34 Joe ISOTYPE
diff --git a/registry-integration-tests/src/test/resources/logback-test.xml b/registry-integration-tests/src/test/resources/logback-test.xml
index 050495d804..bffcae77ec 100644
--- a/registry-integration-tests/src/test/resources/logback-test.xml
+++ b/registry-integration-tests/src/test/resources/logback-test.xml
@@ -7,7 +7,7 @@
-
+
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/config/MyBatisConfiguration.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/config/MyBatisConfiguration.java
index b4236d3ae3..d9482c8463 100644
--- a/registry-persistence/src/main/java/org/gbif/registry/persistence/config/MyBatisConfiguration.java
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/config/MyBatisConfiguration.java
@@ -13,9 +13,13 @@
*/
package org.gbif.registry.persistence.config;
+import java.net.URI;
+import java.util.UUID;
import org.gbif.api.model.collections.Address;
import org.gbif.api.model.collections.Collection;
import org.gbif.api.model.collections.Institution;
+import org.gbif.api.model.collections.descriptors.Descriptor;
+import org.gbif.api.model.collections.descriptors.DescriptorGroup;
import org.gbif.api.model.common.DOI;
import org.gbif.api.model.common.DoiData;
import org.gbif.api.model.common.paging.Pageable;
@@ -30,20 +34,7 @@
import org.gbif.api.model.pipelines.PipelineProcess;
import org.gbif.api.model.pipelines.PipelineStep;
import org.gbif.api.model.predicate.Predicate;
-import org.gbif.api.model.registry.Citation;
-import org.gbif.api.model.registry.Comment;
-import org.gbif.api.model.registry.Contact;
-import org.gbif.api.model.registry.Dataset;
-import org.gbif.api.model.registry.DatasetOccurrenceDownloadUsage;
-import org.gbif.api.model.registry.Endpoint;
-import org.gbif.api.model.registry.Identifier;
-import org.gbif.api.model.registry.Installation;
-import org.gbif.api.model.registry.MachineTag;
-import org.gbif.api.model.registry.Metadata;
-import org.gbif.api.model.registry.Network;
-import org.gbif.api.model.registry.Node;
-import org.gbif.api.model.registry.Organization;
-import org.gbif.api.model.registry.Tag;
+import org.gbif.api.model.registry.*;
import org.gbif.api.model.registry.metasync.MetasyncHistory;
import org.gbif.api.vocabulary.Country;
import org.gbif.api.vocabulary.Language;
@@ -58,13 +49,29 @@
import org.gbif.registry.persistence.mapper.collections.external.IdentifierDto;
import org.gbif.registry.persistence.mapper.collections.external.MachineTagDto;
import org.gbif.registry.persistence.mapper.handler.*;
-import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
+import org.gbif.registry.persistence.mapper.dto.OrganizationGeoJsonDto;
+import org.gbif.registry.persistence.mapper.handler.*;
+import org.gbif.registry.persistence.mapper.handler.CollectionContentTypeArrayTypeHandler;
+import org.gbif.registry.persistence.mapper.handler.CountryNotNullTypeHandler;
+import org.gbif.registry.persistence.mapper.handler.DOITypeHandler;
+import org.gbif.registry.persistence.mapper.handler.DisciplineArrayTypeHandler;
+import org.gbif.registry.persistence.mapper.handler.ExtensionArrayTypeHandler;
+import org.gbif.registry.persistence.mapper.handler.InstitutionGovernanceArrayTypeHandler;
+import org.gbif.registry.persistence.mapper.handler.LocaleTypeHandler;
+import org.gbif.registry.persistence.mapper.handler.MetricInfoTypeHandler;
+import org.gbif.registry.persistence.mapper.handler.OccurrenceDownloadStatusTypeHandler;
+import org.gbif.registry.persistence.mapper.handler.PredicateTypeHandler;
+import org.gbif.registry.persistence.mapper.handler.StepTypeArrayTypeHandler;
+import org.gbif.registry.persistence.mapper.handler.SuggestedChangesTypeHandler;
+import org.gbif.registry.persistence.mapper.handler.UserIdsTypeHandler;
import java.net.URI;
import java.util.UUID;
+import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
@Configuration
public class MyBatisConfiguration {
@@ -128,10 +135,20 @@ ConfigurationCustomizer mybatisConfigCustomizer() {
configuration.getTypeAliasRegistry().registerAlias("Address", Address.class);
configuration.getTypeAliasRegistry().registerAlias("CollectionDto", CollectionDto.class);
configuration.getTypeAliasRegistry().registerAlias("DuplicateDto", DuplicateDto.class);
+ configuration.getTypeAliasRegistry().registerAlias("DescriptorGroup", DescriptorGroup.class);
+ configuration.getTypeAliasRegistry().registerAlias("Descriptor", Descriptor.class);
+ configuration.getTypeAliasRegistry().registerAlias("DescriptorDto", DescriptorDto.class);
+ configuration.getTypeAliasRegistry().registerAlias("VerbatimDto", VerbatimDto.class);
configuration
.getTypeAliasRegistry()
.registerAlias("DuplicateMetadataDto", DuplicateMetadataDto.class);
configuration.getTypeAliasRegistry().registerAlias("SearchDto", SearchDto.class);
+ configuration
+ .getTypeAliasRegistry()
+ .registerAlias("InstitutionSearchDto", InstitutionSearchDto.class);
+ configuration
+ .getTypeAliasRegistry()
+ .registerAlias("CollectionSearchDto", CollectionSearchDto.class);
configuration
.getTypeAliasRegistry()
.registerAlias("InstitutionMatchedDto", InstitutionMatchedDto.class);
@@ -193,8 +210,15 @@ ConfigurationCustomizer mybatisConfigCustomizer() {
.getTypeAliasRegistry()
.registerAlias("ExtensionArrayTypeHandler", ExtensionArrayTypeHandler.class);
configuration
- .getTypeAliasRegistry()
- .registerAlias("InstitutionGovernanceArrayTypeHandler", InstitutionGovernanceArrayTypeHandler.class);
+ .getTypeAliasRegistry()
+ .registerAlias(
+ "InstitutionGovernanceArrayTypeHandler", InstitutionGovernanceArrayTypeHandler.class);
+ configuration
+ .getTypeAliasRegistry()
+ .registerAlias("RankedNameListTypeHandler", RankedNameListTypeHandler.class);
+ configuration
+ .getTypeAliasRegistry()
+ .registerAlias("IntegerArrayTypeHandler", IntegerArrayTypeHandler.class);
configuration.getTypeAliasRegistry().registerAlias("PipelineProcess", PipelineProcess.class);
configuration.getTypeAliasRegistry().registerAlias("Step", PipelineStep.class);
@@ -216,6 +240,9 @@ ConfigurationCustomizer mybatisConfigCustomizer() {
configuration
.getTypeAliasRegistry()
.registerAlias("UserIdsTypeHandler", UserIdsTypeHandler.class);
+ configuration
+ .getTypeAliasRegistry()
+ .registerAlias("OrganizationGeoJsonDto", OrganizationGeoJsonDto.class);
// external iDigBio
configuration.getTypeAliasRegistry().registerAlias("MachineTagDto", MachineTagDto.class);
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/OrganizationMapper.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/OrganizationMapper.java
index 17ec8188c8..340ab28228 100644
--- a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/OrganizationMapper.java
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/OrganizationMapper.java
@@ -20,6 +20,7 @@
import org.gbif.api.vocabulary.InstallationType;
import org.gbif.registry.domain.ws.LegacyOrganizationBriefResponse;
import org.gbif.registry.persistence.ChallengeCodeSupportMapper;
+import org.gbif.registry.persistence.mapper.dto.OrganizationGeoJsonDto;
import org.gbif.registry.persistence.mapper.params.OrganizationListParams;
import java.util.List;
@@ -83,4 +84,10 @@ List hostingInstallationsOf(
List suggest(@Nullable @Param("q") String q);
Organization getLightweight(@Param("key") UUID key);
+
+ /**
+ * @return The list of organizations as geojson
+ */
+ List listGeoJson(@Param("params") OrganizationListParams params);
+
}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/ChangeSuggestionMapper.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/ChangeSuggestionMapper.java
index efae128a5a..fbfa0b7bb6 100644
--- a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/ChangeSuggestionMapper.java
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/ChangeSuggestionMapper.java
@@ -43,6 +43,7 @@ List list(
@Param("entityType") CollectionEntityType entityType,
@Param("proposerEmail") String proposerEmail,
@Param("entityKey") UUID entityKey,
+ @Param("ihIdentifier") String ihIdentifier,
@Nullable @Param("page") Pageable page);
long count(
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/CollectionMapper.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/CollectionMapper.java
index a2ce5f2e58..bcc28c9844 100644
--- a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/CollectionMapper.java
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/CollectionMapper.java
@@ -18,7 +18,7 @@
import org.gbif.registry.persistence.mapper.collections.dto.CollectionDto;
import org.gbif.registry.persistence.mapper.collections.dto.CollectionMatchedDto;
import org.gbif.registry.persistence.mapper.collections.dto.MasterSourceOrganizationDto;
-import org.gbif.registry.persistence.mapper.collections.params.CollectionSearchParams;
+import org.gbif.registry.persistence.mapper.collections.params.CollectionListParams;
import java.util.List;
import java.util.UUID;
@@ -33,9 +33,9 @@
public interface CollectionMapper
extends BaseMapper, LookupMapper {
- List list(@Param("params") CollectionSearchParams searchParams);
+ List list(@Param("params") CollectionListParams searchParams);
- long count(@Param("params") CollectionSearchParams searchParams);
+ long count(@Param("params") CollectionListParams searchParams);
/** A simple suggest by title service. */
List suggest(@Nullable @Param("q") String q);
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/CollectionsSearchMapper.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/CollectionsSearchMapper.java
index 39f8e12952..34b11a0f03 100644
--- a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/CollectionsSearchMapper.java
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/CollectionsSearchMapper.java
@@ -13,22 +13,26 @@
*/
package org.gbif.registry.persistence.mapper.collections;
-import org.gbif.api.vocabulary.Country;
-import org.gbif.registry.persistence.mapper.collections.dto.SearchDto;
-
import java.util.List;
-
import javax.annotation.Nullable;
-
import org.apache.ibatis.annotations.Param;
+import org.gbif.registry.persistence.mapper.collections.dto.CollectionSearchDto;
+import org.gbif.registry.persistence.mapper.collections.dto.InstitutionSearchDto;
+import org.gbif.registry.persistence.mapper.collections.dto.SearchDto;
+import org.gbif.registry.persistence.mapper.collections.params.DescriptorsParams;
+import org.gbif.registry.persistence.mapper.collections.params.FullTextSearchParams;
+import org.gbif.registry.persistence.mapper.collections.params.InstitutionListParams;
public interface CollectionsSearchMapper {
- List search(
- @Nullable @Param("q") String query,
- @Param("highlight") boolean highlight,
- @Nullable @Param("type") String type,
- @Nullable @Param("displayOnNHCPortal") Boolean displayOnNHCPortal,
- @Nullable @Param("country") Country country,
- @Param("limit") int limit);
+ List search(@Nullable @Param("params") FullTextSearchParams params);
+
+ List searchInstitutions(
+ @Nullable @Param("params") InstitutionListParams listParams);
+
+ long countInstitutions(@Nullable @Param("params") InstitutionListParams listParams);
+
+ List searchCollections(@Nullable @Param("params") DescriptorsParams params);
+
+ long countCollections(@Nullable @Param("params") DescriptorsParams listParams);
}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/Common.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/Common.java
new file mode 100644
index 0000000000..e0d814adf0
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/Common.java
@@ -0,0 +1,3 @@
+package org.gbif.registry.persistence.mapper.collections;
+
+public interface Common {}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/DescriptorsMapper.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/DescriptorsMapper.java
new file mode 100644
index 0000000000..69c1b63c3d
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/DescriptorsMapper.java
@@ -0,0 +1,47 @@
+package org.gbif.registry.persistence.mapper.collections;
+
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import org.gbif.api.model.collections.descriptors.DescriptorGroup;
+import org.gbif.registry.persistence.mapper.collections.dto.DescriptorDto;
+import org.gbif.registry.persistence.mapper.collections.dto.VerbatimDto;
+import org.gbif.registry.persistence.mapper.collections.params.DescriptorGroupParams;
+import org.gbif.registry.persistence.mapper.collections.params.DescriptorParams;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface DescriptorsMapper {
+
+ DescriptorGroup getDescriptorGroup(@Param("key") long key);
+
+ void createDescriptorGroup(DescriptorGroup entity);
+
+ void deleteDescriptorGroup(@Param("key") long key);
+
+ void updateDescriptorGroup(DescriptorGroup entity);
+
+ List listDescriptorGroups(@Param("params") DescriptorGroupParams searchParams);
+
+ long countDescriptorGroups(@Param("params") DescriptorGroupParams searchParams);
+
+ DescriptorDto getDescriptor(@Param("key") long key);
+
+ void createDescriptor(DescriptorDto entity);
+
+ void deleteDescriptor(@Param("key") long key);
+
+ List listDescriptors(@Param("params") DescriptorParams searchParams);
+
+ long countDescriptors(@Param("params") DescriptorParams searchParams);
+
+ void deleteDescriptors(@Param("descriptorGroupKey") long descriptorGroupKey);
+
+ void createVerbatim(
+ @Param("descriptorKey") long descriptorKey,
+ @Param("fieldName") String fieldName,
+ @Param("fieldValue") String fieldValue);
+
+ // TODO: list deleted
+
+ List getVerbatimNames(long descriptorGroupKey);
+}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/InstitutionMapper.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/InstitutionMapper.java
index 82360c45d5..4baf47ddea 100644
--- a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/InstitutionMapper.java
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/InstitutionMapper.java
@@ -17,7 +17,7 @@
import org.gbif.api.model.registry.search.collections.KeyCodeNameResult;
import org.gbif.registry.persistence.mapper.collections.dto.InstitutionGeoJsonDto;
import org.gbif.registry.persistence.mapper.collections.dto.InstitutionMatchedDto;
-import org.gbif.registry.persistence.mapper.collections.params.InstitutionSearchParams;
+import org.gbif.registry.persistence.mapper.collections.params.InstitutionListParams;
import java.util.List;
import java.util.UUID;
@@ -32,9 +32,9 @@
public interface InstitutionMapper
extends BaseMapper, LookupMapper {
- List list(@Param("params") InstitutionSearchParams searchParams);
+ List list(@Param("params") InstitutionListParams searchParams);
- long count(@Param("params") InstitutionSearchParams searchParams);
+ long count(@Param("params") InstitutionListParams searchParams);
/** A simple suggest by title service. */
List suggest(@Nullable @Param("q") String q);
@@ -49,7 +49,7 @@ public interface InstitutionMapper
void convertToCollection(
@Param("institutionKey") UUID institutionKey, @Param("collectionKey") UUID collectionKey);
- List listGeoJson(@Param("params") InstitutionSearchParams searchParams);
+ List listGeoJson(@Param("params") InstitutionListParams searchParams);
List getAllKeys();
}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/BaseSearchDto.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/BaseSearchDto.java
new file mode 100644
index 0000000000..aa8664e8fb
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/BaseSearchDto.java
@@ -0,0 +1,55 @@
+package org.gbif.registry.persistence.mapper.collections.dto;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import lombok.Data;
+
+import org.gbif.api.model.collections.AlternativeCode;
+import org.gbif.api.vocabulary.Country;
+import org.gbif.api.vocabulary.License;
+
+@Data
+public abstract class BaseSearchDto {
+
+ private UUID key;
+ private String code;
+ private String name;
+ private String description;
+ private boolean active;
+ private Country country;
+ private Country mailingCountry;
+ private String city;
+ private String mailingCity;
+ private boolean displayOnNHCPortal;
+ private List alternativeCodes = new ArrayList<>();
+ private URI featuredImageUrl;
+ private License featuredImageLicense;
+ private String featuredImageAttribution;
+
+ // highlights
+ private String codeHighlight;
+ private String nameHighlight;
+ private String descriptionHighlight;
+ private String alternativeCodesHighlight;
+ private String addressHighlight;
+ private String cityHighlight;
+ private String provinceHighlight;
+ private String countryHighlight;
+ private String mailAddressHighlight;
+ private String mailCityHighlight;
+ private String mailProvinceHighlight;
+ private String mailCountryHighlight;
+ private String descriptorUsageNameHighlight;
+ private String descriptorCountryHighlight;
+ private String descriptorIdentifiedByHighlight;
+ private String descriptorTypeStatusHighlight;
+ private String descriptorRecordedByHighlight;
+ private String descriptorDisciplineHighlight;
+ private String descriptorObjectClassificationHighlight;
+ private String descriptorIssuesHighlight;
+ private String descriptorGroupTitleHighlight;
+ private String descriptorGroupDescriptionHighlight;
+ private boolean similarityMatch;
+}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/ChangeSuggestionDto.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/ChangeSuggestionDto.java
index 47ec7182b2..b198778899 100644
--- a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/ChangeSuggestionDto.java
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/ChangeSuggestionDto.java
@@ -50,6 +50,8 @@ public class ChangeSuggestionDto {
private String nameNewInstitutionConvertedCollection;
private Date modified;
private String modifiedBy;
+ private String ihIdentifier;
+ private Boolean createInstitution;
// this field is not persisted in the DB. It stores the country that has to be taken into account
// to check the user permissions
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/CollectionSearchDto.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/CollectionSearchDto.java
new file mode 100644
index 0000000000..285242b4ba
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/CollectionSearchDto.java
@@ -0,0 +1,29 @@
+package org.gbif.registry.persistence.mapper.collections.dto;
+
+import java.util.ArrayList;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.gbif.api.vocabulary.collections.MasterSourceType;
+
+@SuppressWarnings("MissingOverride")
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class CollectionSearchDto extends SearchDto {
+
+ private List contentTypes = new ArrayList<>();
+ private boolean personalCollection;
+ private List preservationTypes = new ArrayList<>();
+ private String accessionStatus;
+ private Integer numberSpecimens;
+ private String taxonomicCoverage;
+ private String geographicCoverage;
+ private MasterSourceType masterSource;
+ private String department;
+ private String division;
+ private Integer occurrenceCount;
+ private Integer typeSpecimenCount;
+ private String temporalCoverage;
+ private Float queryRank;
+ private Float queryDescriptorRank;
+}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/DescriptorDto.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/DescriptorDto.java
new file mode 100644
index 0000000000..009a11552e
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/DescriptorDto.java
@@ -0,0 +1,31 @@
+package org.gbif.registry.persistence.mapper.collections.dto;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import lombok.Data;
+import org.gbif.api.v2.RankedName;
+import org.gbif.api.vocabulary.Country;
+import org.gbif.api.vocabulary.Rank;
+
+@Data
+public class DescriptorDto {
+
+ private long key;
+ private Long descriptorGroupKey;
+ private Country country;
+ private Integer individualCount;
+ private List identifiedBy;
+ private Date dateIdentified;
+ private List typeStatus;
+ private List recordedBy;
+ private String discipline;
+ private String objectClassificationName;
+ private List issues;
+ private List verbatim;
+ private Integer usageKey;
+ private String usageName;
+ private Rank usageRank;
+ private List taxonClassification;
+ private Set taxonKeys;
+}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/InstitutionSearchDto.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/InstitutionSearchDto.java
new file mode 100644
index 0000000000..32f7cf2c3f
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/InstitutionSearchDto.java
@@ -0,0 +1,31 @@
+package org.gbif.registry.persistence.mapper.collections.dto;
+
+import java.math.BigDecimal;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.gbif.api.model.collections.AlternativeCode;
+import org.gbif.api.vocabulary.Country;
+import org.gbif.api.vocabulary.License;
+import org.gbif.api.vocabulary.collections.MasterSourceType;
+
+@SuppressWarnings("MissingOverride")
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class InstitutionSearchDto extends BaseSearchDto {
+
+ private List types = new ArrayList<>();
+ private List institutionalGovernances = new ArrayList<>();
+ private List disciplines = new ArrayList<>();
+ private BigDecimal latitude;
+ private BigDecimal longitude;
+ private Integer foundingDate;
+ private Integer numberSpecimens;
+ private MasterSourceType masterSource;
+ private Integer occurrenceCount;
+ private Integer typeSpecimenCount;
+
+}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/SearchDto.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/SearchDto.java
index f680fd444f..4827400df0 100644
--- a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/SearchDto.java
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/SearchDto.java
@@ -13,41 +13,38 @@
*/
package org.gbif.registry.persistence.mapper.collections.dto;
-import org.gbif.api.vocabulary.Country;
-
+import java.util.Date;
+import java.util.List;
import java.util.UUID;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.gbif.api.vocabulary.Country;
+import org.gbif.api.vocabulary.Rank;
-import lombok.Getter;
-import lombok.Setter;
-
-@Getter
-@Setter
-public class SearchDto {
+@SuppressWarnings("MissingOverride")
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class SearchDto extends BaseSearchDto {
private float score;
private String type;
- private UUID key;
- private String code;
- private String name;
private UUID institutionKey;
private String institutionCode;
private String institutionName;
- private boolean displayOnNHCPortal;
- private Country country;
- private Country mailCountry;
-
- private String codeHighlight;
- private String nameHighlight;
- private String descriptionHighlight;
- private String alternativeCodesHighlight;
- private String addressHighlight;
- private String cityHighlight;
- private String provinceHighlight;
- private String countryHighlight;
- private String mailAddressHighlight;
- private String mailCityHighlight;
- private String mailProvinceHighlight;
- private String mailCountryHighlight;
- private boolean similarityMatch;
+ // descriptors fields
+ private Long descriptorKey;
+ private Long descriptorGroupKey;
+ private Long descriptorUsageKey;
+ private String descriptorUsageName;
+ private Rank descriptorUsageRank;
+ private Country descriptorCountry;
+ private Integer descriptorIndividualCount;
+ private List descriptorIdentifiedBy;
+ private Date descriptorDateIdentified;
+ private List descriptorTypeStatus;
+ private List descriptorRecordedBy;
+ private String descriptorDiscipline;
+ private String descriptorObjectClassification;
+ private List descriptorIssues;
}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/VerbatimDto.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/VerbatimDto.java
new file mode 100644
index 0000000000..96a8a8a37c
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/dto/VerbatimDto.java
@@ -0,0 +1,11 @@
+package org.gbif.registry.persistence.mapper.collections.dto;
+
+import lombok.Data;
+
+@Data
+public class VerbatimDto {
+
+ private long key;
+ private String fieldName;
+ private String fieldValue;
+}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/CollectionSearchParams.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/CollectionListParams.java
similarity index 94%
rename from registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/CollectionSearchParams.java
rename to registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/CollectionListParams.java
index bd8b403747..8c6e10b5ee 100644
--- a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/CollectionSearchParams.java
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/CollectionListParams.java
@@ -24,7 +24,7 @@
@Getter
@SuperBuilder
-public class CollectionSearchParams extends SearchParams {
+public class CollectionListParams extends ListParams {
@Nullable List contentTypes;
@Nullable List preservationTypes;
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/DescriptorGroupParams.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/DescriptorGroupParams.java
new file mode 100644
index 0000000000..1b0065b27c
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/DescriptorGroupParams.java
@@ -0,0 +1,19 @@
+package org.gbif.registry.persistence.mapper.collections.params;
+
+import java.util.UUID;
+import javax.annotation.Nullable;
+import lombok.Builder;
+import lombok.Getter;
+import org.gbif.api.model.common.paging.Pageable;
+
+@Getter
+@Builder
+public class DescriptorGroupParams {
+
+ UUID collectionKey;
+ @Nullable String query;
+ @Nullable String title;
+ @Nullable String description;
+ @Nullable Boolean deleted;
+ @Nullable Pageable page;
+}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/DescriptorParams.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/DescriptorParams.java
new file mode 100644
index 0000000000..8aa433450b
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/DescriptorParams.java
@@ -0,0 +1,33 @@
+package org.gbif.registry.persistence.mapper.collections.params;
+
+import java.util.Date;
+import java.util.List;
+import javax.annotation.Nullable;
+import lombok.Builder;
+import lombok.Getter;
+import org.gbif.api.model.common.paging.Pageable;
+import org.gbif.api.vocabulary.Country;
+import org.gbif.api.vocabulary.Rank;
+
+@Getter
+@Builder
+public class DescriptorParams {
+
+ @Nullable String query;
+ @Nullable Long descriptorGroupKey;
+ @Nullable List usageKey;
+ @Nullable List usageName;
+ @Nullable List usageRank;
+ @Nullable List taxonKey;
+ @Nullable List country;
+ @Nullable RangeParam individualCount;
+ @Nullable List identifiedBy;
+ @Nullable Date dateIdentifiedFrom;
+ @Nullable Date dateIdentifiedBefore;
+ @Nullable List typeStatus;
+ @Nullable List recordedBy;
+ @Nullable List discipline;
+ @Nullable List objectClassification;
+ @Nullable List issues;
+ @Nullable Pageable page;
+}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/DescriptorVerbatimParams.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/DescriptorVerbatimParams.java
new file mode 100644
index 0000000000..ba40d0c8f6
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/DescriptorVerbatimParams.java
@@ -0,0 +1,17 @@
+package org.gbif.registry.persistence.mapper.collections.params;
+
+import org.gbif.api.model.common.paging.Pageable;
+
+import javax.annotation.Nullable;
+
+import lombok.Builder;
+import lombok.Getter;
+
+@Getter
+@Builder
+public class DescriptorVerbatimParams {
+
+ @Nullable String query;
+ @Nullable Long recordKey;
+ @Nullable Pageable page;
+}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/DescriptorsParams.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/DescriptorsParams.java
new file mode 100644
index 0000000000..3468351ece
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/DescriptorsParams.java
@@ -0,0 +1,65 @@
+package org.gbif.registry.persistence.mapper.collections.params;
+
+import java.time.LocalDate;
+import java.util.List;
+import javax.annotation.Nullable;
+import lombok.Getter;
+import lombok.experimental.SuperBuilder;
+import org.gbif.api.vocabulary.Country;
+import org.gbif.api.vocabulary.Rank;
+
+@Getter
+@SuperBuilder
+public class DescriptorsParams extends CollectionListParams {
+
+ // descriptors fields
+ List usageName;
+ List usageKey;
+ List usageRank;
+ List taxonKey;
+ @Nullable List descriptorCountry;
+ @Nullable RangeParam individualCount;
+ @Nullable List identifiedBy;
+ @Nullable LocalDate dateIdentifiedFrom;
+ @Nullable LocalDate dateIdentifiedBefore;
+ @Nullable List typeStatus;
+ @Nullable List recordedBy;
+ @Nullable List discipline;
+ @Nullable List objectClassification;
+ @Nullable List issues;
+
+ public boolean descriptorSearch() {
+ return query != null
+ || usageName != null
+ || usageKey != null
+ || usageRank != null
+ || taxonKey != null
+ || descriptorCountry != null
+ || individualCount != null
+ || identifiedBy != null
+ || dateIdentifiedFrom != null
+ || dateIdentifiedBefore != null
+ || typeStatus != null
+ || recordedBy != null
+ || discipline != null
+ || objectClassification != null
+ || issues != null;
+ }
+
+ public boolean descriptorSearchWithoutQuery() {
+ return usageName != null
+ || usageKey != null
+ || usageRank != null
+ || taxonKey != null
+ || descriptorCountry != null
+ || individualCount != null
+ || identifiedBy != null
+ || dateIdentifiedFrom != null
+ || dateIdentifiedBefore != null
+ || typeStatus != null
+ || recordedBy != null
+ || discipline != null
+ || objectClassification != null
+ || issues != null;
+ }
+}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/FullTextSearchParams.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/FullTextSearchParams.java
new file mode 100644
index 0000000000..2a363d7a7c
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/FullTextSearchParams.java
@@ -0,0 +1,18 @@
+package org.gbif.registry.persistence.mapper.collections.params;
+
+import javax.annotation.Nullable;
+import lombok.Builder;
+import lombok.Data;
+import org.gbif.api.vocabulary.Country;
+
+@Data
+@Builder
+public class FullTextSearchParams {
+
+ @Nullable String query;
+ boolean highlight;
+ @Nullable String type;
+ @Nullable Boolean displayOnNHCPortal;
+ @Nullable Country country;
+ int limit;
+}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/InstitutionSearchParams.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/InstitutionListParams.java
similarity index 94%
rename from registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/InstitutionSearchParams.java
rename to registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/InstitutionListParams.java
index 6a9348eb9a..efac8f9c1e 100644
--- a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/InstitutionSearchParams.java
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/InstitutionListParams.java
@@ -24,7 +24,7 @@
@Getter
@SuperBuilder
-public class InstitutionSearchParams extends SearchParams {
+public class InstitutionListParams extends ListParams {
@Nullable List types;
@Nullable List institutionalGovernances;
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/ListParams.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/ListParams.java
new file mode 100644
index 0000000000..e6f7317ba0
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/ListParams.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.gbif.registry.persistence.mapper.collections.params;
+
+import java.util.List;
+import java.util.UUID;
+import javax.annotation.Nullable;
+import lombok.Getter;
+import lombok.experimental.SuperBuilder;
+import org.gbif.api.model.common.paging.Pageable;
+import org.gbif.api.vocabulary.CollectionsSortField;
+import org.gbif.api.vocabulary.Country;
+import org.gbif.api.vocabulary.IdentifierType;
+import org.gbif.api.vocabulary.SortOrder;
+import org.gbif.api.vocabulary.collections.MasterSourceType;
+
+@Getter
+@SuperBuilder
+public abstract class ListParams {
+
+ @Nullable Boolean highlight;
+ @Nullable String query;
+ @Nullable String code;
+ @Nullable String name;
+ @Nullable String alternativeCode;
+ @Nullable String machineTagNamespace;
+ @Nullable String machineTagName;
+ @Nullable String machineTagValue;
+ @Nullable IdentifierType identifierType;
+ @Nullable String identifier;
+ @Nullable List countries;
+ @Nullable List regionCountries;
+ @Nullable String city;
+ @Nullable String fuzzyName;
+ @Nullable Boolean active;
+ @Nullable MasterSourceType masterSourceType;
+ @Nullable RangeParam numberSpecimens;
+ @Nullable Boolean displayOnNHCPortal;
+ @Nullable RangeParam occurrenceCount;
+ @Nullable RangeParam typeSpecimenCount;
+ @Nullable List institutionKeys;
+ @Nullable CollectionsSortField sortBy;
+ @Nullable SortOrder sortOrder;
+ @Nullable private Boolean deleted;
+ @Nullable private UUID replacedBy;
+ @Nullable private Pageable page;
+}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/SearchParams.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/SearchParams.java
index 58eb1986c9..28cad8be2c 100644
--- a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/SearchParams.java
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/collections/params/SearchParams.java
@@ -1,60 +1,46 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
package org.gbif.registry.persistence.mapper.collections.params;
-import org.gbif.api.model.common.paging.Pageable;
-import org.gbif.api.vocabulary.CollectionsSortField;
-import org.gbif.api.vocabulary.Country;
-import org.gbif.api.vocabulary.IdentifierType;
-import org.gbif.api.vocabulary.SortOrder;
-import org.gbif.api.vocabulary.collections.MasterSourceType;
-
+import java.util.Date;
import java.util.List;
-import java.util.UUID;
-
import javax.annotation.Nullable;
+import lombok.Builder;
+import lombok.Data;
+import org.gbif.api.vocabulary.Country;
+import org.gbif.api.vocabulary.Rank;
+import org.gbif.api.vocabulary.TypeStatus;
-import lombok.Getter;
-import lombok.experimental.SuperBuilder;
-
-@Getter
-@SuperBuilder
-public abstract class SearchParams {
+@Data
+@Builder
+public class SearchParams {
- @Nullable String query;
- @Nullable String code;
- @Nullable String name;
- @Nullable String alternativeCode;
- @Nullable String machineTagNamespace;
- @Nullable String machineTagName;
- @Nullable String machineTagValue;
- @Nullable IdentifierType identifierType;
- @Nullable String identifier;
+ @Nullable String q;
+ Boolean highlight;
+ String type;
+ Boolean displayOnNHCPortal;
@Nullable List countries;
@Nullable List regionCountries;
@Nullable String city;
- @Nullable String fuzzyName;
- @Nullable Boolean active;
- @Nullable MasterSourceType masterSourceType;
- @Nullable RangeParam numberSpecimens;
- @Nullable Boolean displayOnNHCPortal;
- @Nullable RangeParam occurrenceCount;
- @Nullable RangeParam typeSpecimenCount;
- @Nullable List institutionKeys;
- @Nullable CollectionsSortField sortBy;
- @Nullable SortOrder sortOrder;
- @Nullable private Boolean deleted;
- @Nullable private UUID replacedBy;
- @Nullable private Pageable page;
+
+ Integer limit;
+ Integer offset;
+
+ // collection fields
+
+ // descriptors fields
+ List usageName;
+ List usageKey;
+ List usageRank;
+ List taxonKey;
+ @Nullable List descriptorCountry;
+ @Nullable RangeParam individualCount;
+ @Nullable List identifiedBy;
+ @Nullable
+ Date dateIdentified;
+ @Nullable Date dateIdentifiedFrom;
+ @Nullable Date dateIdentifiedBefore;
+ @Nullable List typeStatus;
+ @Nullable List recordedBy;
+ @Nullable List discipline;
+ @Nullable List objectClassification;
+ @Nullable List issues;
}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/dto/OrganizationGeoJsonDto.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/dto/OrganizationGeoJsonDto.java
new file mode 100644
index 0000000000..5d8fe5f8c8
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/dto/OrganizationGeoJsonDto.java
@@ -0,0 +1,17 @@
+package org.gbif.registry.persistence.mapper.dto;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import lombok.Data;
+
+@Data
+public class OrganizationGeoJsonDto {
+
+ private UUID key;
+ private String title;
+ private Integer numPublishedDatasets;
+ private BigDecimal latitude;
+ private BigDecimal longitude;
+
+}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/handler/IntegerArrayTypeHandler.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/handler/IntegerArrayTypeHandler.java
new file mode 100644
index 0000000000..1f00ebaa26
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/handler/IntegerArrayTypeHandler.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.gbif.registry.persistence.mapper.handler;
+
+import com.google.common.base.Strings;
+import java.sql.Array;
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.gbif.api.vocabulary.collections.PreservationType;
+
+/** {@link org.apache.ibatis.type.TypeHandler} for arrays of {@link PreservationType}. */
+public class IntegerArrayTypeHandler extends BaseTypeHandler> {
+
+ @Override
+ public void setNonNullParameter(
+ PreparedStatement ps, int i, Set parameter, JdbcType jdbcType) throws SQLException {
+ Array array = ps.getConnection().createArrayOf("integer", parameter.toArray());
+ ps.setArray(i, array);
+ }
+
+ @Override
+ public Set getNullableResult(ResultSet rs, String columnName) throws SQLException {
+ return toSet(rs.getArray(columnName));
+ }
+
+ @Override
+ public Set getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+ return toSet(rs.getArray(columnIndex));
+ }
+
+ @Override
+ public Set getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+ return toSet(cs.getArray(columnIndex));
+ }
+
+ private Set toSet(Array pgArray) throws SQLException {
+ if (pgArray == null) {
+ return new HashSet<>();
+ }
+
+ String[] strings = (String[]) pgArray.getArray();
+ if (strings != null && strings.length > 0) {
+ return Arrays.stream(strings)
+ .filter(v -> !Strings.isNullOrEmpty(v))
+ .map(Integer::valueOf)
+ .collect(Collectors.toSet());
+ }
+ return new HashSet<>();
+ }
+}
diff --git a/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/handler/RankedNameListTypeHandler.java b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/handler/RankedNameListTypeHandler.java
new file mode 100644
index 0000000000..27b35e1a94
--- /dev/null
+++ b/registry-persistence/src/main/java/org/gbif/registry/persistence/mapper/handler/RankedNameListTypeHandler.java
@@ -0,0 +1,74 @@
+package org.gbif.registry.persistence.mapper.handler;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectReader;
+import com.google.common.base.Strings;
+import java.io.IOException;
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.gbif.api.v2.RankedName;
+
+public class RankedNameListTypeHandler extends BaseTypeHandler> {
+
+ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+ private static final ObjectReader OBJECT_READER =
+ OBJECT_MAPPER.readerFor(new TypeReference>() {});
+
+ @Override
+ public void setNonNullParameter(
+ PreparedStatement preparedStatement,
+ int i,
+ List rankedNamesList,
+ JdbcType jdbcType)
+ throws SQLException {
+ preparedStatement.setString(i, toString(rankedNamesList));
+ }
+
+ @Override
+ public List getNullableResult(ResultSet resultSet, String columnName)
+ throws SQLException {
+ return fromString(resultSet.getString(columnName));
+ }
+
+ @Override
+ public List getNullableResult(ResultSet resultSet, int columnIndex)
+ throws SQLException {
+ return fromString(resultSet.getString(columnIndex));
+ }
+
+ @Override
+ public List getNullableResult(CallableStatement callableStatement, int columnIndex)
+ throws SQLException {
+ return fromString(callableStatement.getString(columnIndex));
+ }
+
+ private String toString(List rankedNamesList) {
+ try {
+ return OBJECT_MAPPER.writeValueAsString(rankedNamesList);
+ } catch (JsonProcessingException e) {
+ throw new IllegalStateException(
+ "Couldn't convert language map to JSON: " + rankedNamesList.toString(), e);
+ }
+ }
+
+ private List fromString(String json) {
+ if (Strings.isNullOrEmpty(json)) {
+ return Collections.emptyList();
+ }
+
+ try {
+ return OBJECT_READER.readValue(json);
+ } catch (IOException e) {
+ throw new IllegalStateException(
+ "Couldn't deserialize taxon classification JSON from DB: " + json, e);
+ }
+ }
+}
diff --git a/registry-persistence/src/main/resources/liquibase/138-dataset-occurrence-download-created-index.xml b/registry-persistence/src/main/resources/liquibase/138-dataset-occurrence-download-created-index.xml
index d566fcb896..e87bf7c273 100644
--- a/registry-persistence/src/main/resources/liquibase/138-dataset-occurrence-download-created-index.xml
+++ b/registry-persistence/src/main/resources/liquibase/138-dataset-occurrence-download-created-index.xml
@@ -1,7 +1,7 @@
+ xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd">
diff --git a/registry-persistence/src/main/resources/liquibase/139-dataset-occurrence-download-created-index.xml b/registry-persistence/src/main/resources/liquibase/139-dataset-occurrence-download-created-index.xml
index 4f774caafa..1f8df66a60 100644
--- a/registry-persistence/src/main/resources/liquibase/139-dataset-occurrence-download-created-index.xml
+++ b/registry-persistence/src/main/resources/liquibase/139-dataset-occurrence-download-created-index.xml
@@ -1,7 +1,7 @@
+ xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd">
diff --git a/registry-persistence/src/main/resources/liquibase/140-ih-identifier-change-sugestion.xml b/registry-persistence/src/main/resources/liquibase/140-ih-identifier-change-sugestion.xml
new file mode 100644
index 0000000000..9247a8b269
--- /dev/null
+++ b/registry-persistence/src/main/resources/liquibase/140-ih-identifier-change-sugestion.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/registry-persistence/src/main/resources/liquibase/141-collection-descriptors-grscicoll.xml b/registry-persistence/src/main/resources/liquibase/141-collection-descriptors-grscicoll.xml
new file mode 100644
index 0000000000..9ea354fa83
--- /dev/null
+++ b/registry-persistence/src/main/resources/liquibase/141-collection-descriptors-grscicoll.xml
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
diff --git a/registry-persistence/src/main/resources/liquibase/master.xml b/registry-persistence/src/main/resources/liquibase/master.xml
index 3b9c9e49bc..c76008c0c0 100644
--- a/registry-persistence/src/main/resources/liquibase/master.xml
+++ b/registry-persistence/src/main/resources/liquibase/master.xml
@@ -145,4 +145,6 @@
+
+
diff --git a/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/OrganizationMapper.xml b/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/OrganizationMapper.xml
index adcd758856..380f2a9a22 100644
--- a/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/OrganizationMapper.xml
+++ b/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/OrganizationMapper.xml
@@ -29,6 +29,12 @@
+
+
+
+
+
+
key,endorsing_node_key,password,title,abbreviation,description,language,email,
phone,homepage,logo_url,address,city,province,country,postal_code,latitude,longitude,created,created_by,
@@ -485,6 +491,15 @@
+
+
diff --git a/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/ChangeSuggestionMapper.xml b/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/ChangeSuggestionMapper.xml
index fcfa3f0baa..9560e9a4ad 100644
--- a/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/ChangeSuggestionMapper.xml
+++ b/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/ChangeSuggestionMapper.xml
@@ -12,14 +12,14 @@
entity_type, entity_key, type, status, proposed, proposed_by, proposer_email, changes, comments,
suggested_entity, merge_target_key, institution_converted_collection, name_new_institution_converted_collection,
- modified, modified_by
+ modified, modified_by, ih_identifier, create_institution
cs.key, cs.entity_type, cs.entity_key, cs.type, cs.status, cs.proposed, cs.proposed_by, cs.proposer_email, cs. applied,
cs.applied_by, cs.discarded_by, cs.discarded, cs.suggested_entity, cs.comments,
cs.merge_target_key, cs.changes, cs.institution_converted_collection, cs.name_new_institution_converted_collection,
- cs.modified, cs.modified_by
+ cs.modified, cs.modified_by, cs.ih_identifier, cs.create_institution
@@ -37,7 +37,9 @@
#{institutionConvertedCollection,jdbcType=OTHER},
#{nameNewInstitutionConvertedCollection,jdbcType=VARCHAR},
now(),
- #{modifiedBy,jdbcType=VARCHAR}
+ #{modifiedBy,jdbcType=VARCHAR},
+ #{ihIdentifier, jdbcType=VARCHAR},
+ #{createInstitution, jdbcType=BOOLEAN}
@@ -94,6 +96,9 @@
AND cs.entity_key = #{entityKey,jdbcType=OTHER}
+
+ AND cs.ih_identifier = #{ihIdentifier, jdbcType=OTHER}
+
ORDER BY cs.proposed DESC
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 e3ed1c3978..0950775d65 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
@@ -201,28 +201,16 @@
, inst.name institutionName, inst.code institutionCode, c.fulltext_search
,query
,similarity(c.name, #{params.fuzzyName,jdbcType=VARCHAR}) AS similarity_score
-
+ FROM collection c
+
+
+
+
) AS c
ORDER BY
-
-
-
- c.number_specimens
-
-
-
-
-
-
- DESC
-
-
- ASC
-
-
-
- NULLS LAST,
-
+
+
+
ts_rank_cd(c.fulltext_search, query) DESC,
similarity_score DESC,
c.created DESC, c.key
@@ -233,15 +221,15 @@
- FROM collection c
LEFT JOIN institution inst ON inst.key = c.institution_key
-
-
-
INNER JOIN collection_machine_tag cmt on cmt.collection_key = c.key
INNER JOIN machine_tag mt on mt.key = cmt.machine_tag_key
@@ -250,10 +238,8 @@
INNER JOIN collection_identifier ci on ci.collection_key = c.key
INNER JOIN identifier id on id.key = ci.identifier_key
-
- LEFT JOIN address addr ON addr.key = c.address_key
- LEFT JOIN address mail_addr ON mail_addr.key = c.mailing_address_key
-
+ LEFT JOIN address addr ON addr.key = c.address_key
+ LEFT JOIN address mail_addr ON mail_addr.key = c.mailing_address_key
INNER JOIN master_sync_metadata m ON c.master_sync_metadata_key = m.key
diff --git a/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/CollectionsSearchMapper.xml b/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/CollectionsSearchMapper.xml
index cf86c3b7e1..a876547da2 100644
--- a/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/CollectionsSearchMapper.xml
+++ b/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/CollectionsSearchMapper.xml
@@ -3,130 +3,445 @@
-
+
+
+
+ i.key, i.code, i.name, i.description, i.alternative_codes,
+ i.display_on_NHCPortal AS displayOnNHCPortal,'institution' AS type,
+ i.address_key, i.mailing_address_key, null::uuid institution_key, null institution_name, null institution_code
+
+
+
+ c.key, c.code, c.name, c.description, c.alternative_codes,
+ c.display_on_NHCPortal AS displayOnNHCPortal,'collection' AS type,
+ c.address_key, c.mailing_address_key, i.key institution_key, i.name institution_name, i.code institution_code
+
+
+
+ to_tsquery('english',regexp_replace(quote_literal(unaccent(trim(#{params.query}))),'\s+',':*&','g')||':*')
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ JOIN to_tsquery('english',regexp_replace(quote_literal(unaccent(trim(#{params.query}))),'\s+',':*&','g')||':*') AS query ON query @@ fulltext_search
+ OR EXISTS(
+ SELECT collection_contact_key
+ FROM institution_collection_contact JOIN collection_contact cc ON cc.key = collection_contact_key
+ WHERE institution_key = i.key AND query @@ cc.fulltext_search
+ )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AND d.usage_key IN
+
+ #{item,jdbcType=INTEGER}
+
+
+
+ AND d.usage_name IN
+
+ #{item,jdbcType=VARCHAR}
+
+
+
+ AND d.usage_rank IN
+
+ #{item,jdbcType=VARCHAR}
+
+
+
+ AND d.taxon_keys && ARRAY
+
+ #{item,jdbcType=INTEGER}
+
+
+
+
+
+ AND d.individual_count = #{params.individualCount.exactValue,jdbcType=INTEGER}
+
+
+
+ AND d.individual_count >= #{params.individualCount.lowerBound,jdbcType=INTEGER}
+
+
+ AND d.individual_count <= #{params.individualCount.higherBound,jdbcType=INTEGER}
+
+
+
+
+
+ AND d.identified_by && ARRAY
+
+ #{item,jdbcType=VARCHAR}::text
+
+
+ AND d.date_identified >= #{params.dateIdentifiedFrom}
+ AND d.date_identified < #{params.dateIdentifiedBefore}
+
+
+ AND d.type_status && ARRAY
+
+ #{item,jdbcType=VARCHAR}::text
+
+
+
+ AND d.recorded_by && ARRAY
+
+ #{item,jdbcType=VARCHAR}::text
+
+
+
+ AND d.discipline IN
+
+ #{item,jdbcType=VARCHAR}
+
+
+
+ AND d.object_classification_name IN
+
+ #{item,jdbcType=VARCHAR}
+
+
+
+ AND d.country IN
+
+ #{item,jdbcType=VARCHAR}
+
+
+
+ AND d.issues && ARRAY
+
+ #{item,jdbcType=VARCHAR}::text
+
+
+
+
+
+ JOIN to_tsquery('english',regexp_replace(quote_literal(unaccent(trim(#{params.query}))),'\s+',':*&','g')||':*') AS query ON query @@ c.fulltext_search
+ OR EXISTS(
+ SELECT collection_contact_key
+ FROM collection_collection_contact JOIN collection_contact cc ON cc.key = collection_contact_key
+ WHERE collection_key = c.key AND query @@ cc.fulltext_search
+ )
+ OR @@ d.fulltext_search
+ OR @@ ds.fulltext_search
+
+
diff --git a/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/Common.xml b/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/Common.xml
new file mode 100644
index 0000000000..f6160f87a7
--- /dev/null
+++ b/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/Common.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${alias}number_specimens
+
+
+
+
+
+
+ DESC
+
+
+ ASC
+
+
+
+ NULLS LAST,
+
+
+
+
diff --git a/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/DescriptorsMapper.xml b/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/DescriptorsMapper.xml
new file mode 100644
index 0000000000..c4946bfaf9
--- /dev/null
+++ b/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/DescriptorsMapper.xml
@@ -0,0 +1,323 @@
+
+
+
+
+
+
+
+
+
+ title, description, collection_key, created, created_by, modified, modified_by
+
+
+
+ ds.key, ds.title, ds.description, ds.collection_key, ds.created, ds.created_by, ds.modified, ds.modified_by,
+ ds.deleted
+
+
+
+ #{title,jdbcType=VARCHAR},
+ #{description,jdbcType=VARCHAR},
+ #{collectionKey,jdbcType=OTHER},
+ now(),
+ #{createdBy,jdbcType=VARCHAR},
+ now(),
+ #{modifiedBy,jdbcType=VARCHAR}
+
+
+
+ title = #{title,jdbcType=VARCHAR},
+ description = #{description,jdbcType=VARCHAR},
+ modified_by = #{modifiedBy,jdbcType=VARCHAR},
+ modified = now(),
+ deleted = null
+
+
+
+
+ JOIN to_tsquery('english',regexp_replace(quote_literal(unaccent(trim(#{params.query}))),'\s+',':*&','g')||':*')
+ AS query ON query @@ fulltext_search
+
+
+
+ INSERT INTO collection_descriptor_group()
+ VALUES()
+
+
+
+ UPDATE collection_descriptor_group
+ SET
+
+ WHERE key = #{key,jdbcType=OTHER}
+
+
+
+ UPDATE collection_descriptor_group
+ SET deleted = now()
+ WHERE key = #{key,jdbcType=OTHER} AND deleted IS NULL
+
+
+
+
+
+
+
+
+
+ FROM collection_descriptor_group ds
+
+
+
+
+
+
+ ds.deleted IS NOT NULL
+
+
+ ds.deleted IS NULL
+
+
+
+ AND ds.collection_key = #{params.collectionKey,jdbcType=OTHER}
+
+
+ AND lower(ds.title) = lower(#{params.title,jdbcType=VARCHAR})
+
+
+ AND lower(ds.description) = lower(#{params.description,jdbcType=VARCHAR})
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ collection_descriptor_group_key, usage_key, usage_name, usage_rank, taxon_classification, taxon_keys, country,
+ individual_count, identified_by, date_identified, type_status, recorded_by, discipline, object_classification_name,
+ issues
+
+
+
+ d.key, d.collection_descriptor_group_key, d.usage_key, d.usage_name, d.usage_rank, d.taxon_classification, d.country,
+ d.individual_count, d.identified_by, d.date_identified, d.type_status, d.recorded_by, d.discipline,
+ d.object_classification_name, d.issues
+
+
+
+ #{descriptorGroupKey,jdbcType=INTEGER},
+ #{usageKey,jdbcType=INTEGER},
+ #{usageName,jdbcType=VARCHAR},
+ #{usageRank,jdbcType=VARCHAR},
+ #{taxonClassification,jdbcType=OTHER,typeHandler=RankedNameListTypeHandler}::jsonb,
+ #{taxonKeys,jdbcType=ARRAY,typeHandler=IntegerArrayTypeHandler},
+ #{country,jdbcType=VARCHAR},
+ #{individualCount,jdbcType=INTEGER},
+ #{identifiedBy,jdbcType=ARRAY,typeHandler=StringArrayTypeHandler},
+ #{dateIdentified,jdbcType=OTHER},
+ #{typeStatus,jdbcType=ARRAY,typeHandler=StringArrayTypeHandler},
+ #{recordedBy,jdbcType=ARRAY,typeHandler=StringArrayTypeHandler},
+ #{discipline,jdbcType=VARCHAR},
+ #{objectClassificationName,jdbcType=VARCHAR},
+ #{issues,jdbcType=ARRAY,typeHandler=StringArrayTypeHandler}
+
+
+
+ INSERT INTO collection_descriptor()
+ VALUES()
+
+
+
+ DELETE FROM collection_descriptor
+ WHERE collection_descriptor_group_key = #{descriptorGroupKey,jdbcType=INTEGER}
+
+
+
+
+
+
+
+
+
+ FROM collection_descriptor d
+ INNER JOIN collection_descriptor_group ds ON ds.key = d.collection_descriptor_group_key AND ds.deleted IS NULL
+
+
+
+
+
+ AND d.collection_descriptor_group_key = #{params.descriptorGroupKey,jdbcType=OTHER}
+
+
+ AND d.usage_key IN
+
+ #{item,jdbcType=INTEGER}
+
+
+
+ AND d.usage_name IN
+
+ #{item,jdbcType=VARCHAR}
+
+
+
+ AND d.usage_rank IN
+
+ #{item,jdbcType=VARCHAR}
+
+
+
+ AND d.taxon_keys && ARRAY
+
+ #{item,jdbcType=INTEGER}
+
+
+
+
+
+ AND d.individual_count = #{params.individualCount.exactValue,jdbcType=INTEGER}
+
+
+
+ AND d.individual_count >= #{params.individualCount.lowerBound,jdbcType=INTEGER}
+
+
+ AND d.individual_count <= #{params.individualCount.higherBound,jdbcType=INTEGER}
+
+
+
+
+
+ AND d.identified_by && ARRAY
+
+ #{item,jdbcType=VARCHAR}::text
+
+
+ AND d.date_identified >= #{params.dateIdentifiedFrom}
+ AND d.date_identified < #{params.dateIdentifiedBefore}
+
+
+ AND d.type_status && ARRAY
+
+ #{item,jdbcType=VARCHAR}::text
+
+
+
+ AND d.recorded_by && ARRAY
+
+ #{item,jdbcType=VARCHAR}::text
+
+
+
+ AND d.discipline IN
+
+ #{item,jdbcType=VARCHAR}
+
+
+
+ AND d.object_classification_name IN
+
+ #{item,jdbcType=VARCHAR}
+
+
+
+ AND d.country IN
+
+ #{item,jdbcType=VARCHAR}
+
+
+
+ AND d.issues && ARRAY
+
+ #{item,jdbcType=VARCHAR}::text
+
+
+
+
+
+
+
+
+
+
+
+ collection_descriptor_key, field_name, field_value
+
+
+
+ v.key, v.collection_descriptor_key, v.field_name, v.field_value
+
+
+
+ #{descriptorKey,jdbcType=INTEGER},
+ #{fieldName,jdbcType=VARCHAR},
+ #{fieldValue,jdbcType=VARCHAR}
+
+
+
+ INSERT INTO collection_descriptor_verbatim()
+ VALUES()
+
+
+
+
+
+
+
diff --git a/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/InstitutionMapper.xml b/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/InstitutionMapper.xml
index 91d9c8c91a..f6c5d3c365 100644
--- a/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/InstitutionMapper.xml
+++ b/registry-persistence/src/main/resources/org/gbif/registry/persistence/mapper/collections/InstitutionMapper.xml
@@ -201,28 +201,16 @@
, i.fulltext_search
,query
,similarity(i.name, #{params.fuzzyName,jdbcType=VARCHAR}) AS similarity_score
-
+ FROM institution i
+
+
+
+
) AS i
ORDER BY
-
-
-
- i.number_specimens
-
-
-
-
-
-
- DESC
-
-
- ASC
-
-
-
- NULLS LAST,
-
+
+
+
ts_rank_cd(i.fulltext_search, query) DESC,
similarity_score DESC,
i.created DESC, i.key
@@ -233,6 +221,10 @@
@@ -242,6 +234,10 @@
similarity_score, i.key)
i.key, i.name, i.latitude, i.longitude
,similarity(i.name, #{params.fuzzyName,jdbcType=VARCHAR}) AS similarity_score
+ FROM institution i
+
+
+
AND i.latitude IS NOT NULL AND i.longitude IS NOT NULL
ORDER BY ts_rank_cd(i.fulltext_search, query) DESC,
@@ -253,10 +249,6 @@
- FROM institution i
-
-
-
INNER JOIN institution_machine_tag imt on imt.institution_key = i.key
INNER JOIN machine_tag mt on mt.key = imt.machine_tag_key
@@ -265,10 +257,8 @@
INNER JOIN institution_identifier ii on ii.institution_key = i.key
INNER JOIN identifier id on id.key = ii.identifier_key
-
- LEFT JOIN address addr ON addr.key = i.address_key
- LEFT JOIN address mail_addr ON mail_addr.key = i.mailing_address_key
-
+ LEFT JOIN address addr ON addr.key = i.address_key
+ LEFT JOIN address mail_addr ON mail_addr.key = i.mailing_address_key
INNER JOIN master_sync_metadata m ON i.master_sync_metadata_key = m.key
diff --git a/registry-search/src/main/java/org/gbif/registry/search/dataset/service/collections/CollectionsSearchService.java b/registry-search/src/main/java/org/gbif/registry/search/dataset/service/collections/CollectionsSearchService.java
deleted file mode 100644
index 40eb5bd0e1..0000000000
--- a/registry-search/src/main/java/org/gbif/registry/search/dataset/service/collections/CollectionsSearchService.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.gbif.registry.search.dataset.service.collections;
-
-import org.gbif.api.model.collections.search.CollectionsSearchResponse;
-import org.gbif.api.vocabulary.Country;
-import org.gbif.registry.domain.collections.TypeParam;
-import org.gbif.registry.persistence.mapper.collections.CollectionsSearchMapper;
-import org.gbif.registry.persistence.mapper.collections.dto.SearchDto;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.UUID;
-import java.util.regex.Pattern;
-
-import org.elasticsearch.common.Strings;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-/** Service to lookup GRSciColl institutions and collections. */
-@Service
-public class CollectionsSearchService {
-
- private static final Pattern HIGHLIGHT_PATTERN = Pattern.compile(".*.+.*");
-
- private final CollectionsSearchMapper searchMapper;
-
- @Autowired
- public CollectionsSearchService(CollectionsSearchMapper searchMapper) {
- this.searchMapper = searchMapper;
- }
-
- public List search(
- String query,
- boolean highlight,
- TypeParam type,
- Boolean displayOnNHCPortal,
- Country country,
- int limit) {
- List dtos =
- searchMapper.search(
- query,
- highlight,
- type != null ? type.name() : null,
- displayOnNHCPortal,
- country,
- limit);
-
- // the query can return duplicates so we need an auxiliary map to filter duplicates
- Map responsesMap = new HashMap<>();
- List responses = new ArrayList<>();
- dtos.forEach(
- dto -> {
- if (responsesMap.containsKey(dto.getKey())) {
- if (highlight) {
- CollectionsSearchResponse existing = responsesMap.get(dto.getKey());
- addMatches(existing, dto);
- }
- return;
- }
-
- CollectionsSearchResponse response = new CollectionsSearchResponse();
- response.setType(dto.getType());
- response.setCode(dto.getCode());
- response.setKey(dto.getKey());
- response.setName(dto.getName());
- response.setDisplayOnNHCPortal(dto.isDisplayOnNHCPortal());
- response.setCountry(dto.getCountry());
- response.setMailingCountry(dto.getMailCountry());
-
- if (dto.getType().equals("collection")) {
- response.setInstitutionKey(dto.getInstitutionKey());
- response.setInstitutionCode(dto.getInstitutionCode());
- response.setInstitutionName(dto.getInstitutionName());
- }
-
- if (highlight) {
- addMatches(response, dto);
- }
-
- responses.add(response);
- responsesMap.put(dto.getKey(), response);
- });
-
- return responses;
- }
-
- private void addMatches(CollectionsSearchResponse response, SearchDto dto) {
- Set matches = new HashSet<>();
- createHighlightMatch(dto.getCodeHighlight(), "code").ifPresent(matches::add);
- createHighlightMatch(dto.getDescriptionHighlight(), "description").ifPresent(matches::add);
- createHighlightMatch(dto.getAlternativeCodesHighlight(), "alternativeCode")
- .ifPresent(matches::add);
- createHighlightMatch(dto.getAddressHighlight(), "address").ifPresent(matches::add);
- createHighlightMatch(dto.getCityHighlight(), "city").ifPresent(matches::add);
- createHighlightMatch(dto.getProvinceHighlight(), "province").ifPresent(matches::add);
- createHighlightMatch(dto.getCountryHighlight(), "country").ifPresent(matches::add);
- createHighlightMatch(dto.getMailAddressHighlight(), "mailingAddress").ifPresent(matches::add);
- createHighlightMatch(dto.getMailCityHighlight(), "mailingCity").ifPresent(matches::add);
- createHighlightMatch(dto.getMailProvinceHighlight(), "mailingProvince").ifPresent(matches::add);
- createHighlightMatch(dto.getMailCountryHighlight(), "mailingCountry").ifPresent(matches::add);
-
- Optional nameMatch =
- createHighlightMatch(dto.getNameHighlight(), "name");
- if (nameMatch.isPresent()) {
- matches.add(nameMatch.get());
- } else if (dto.isSimilarityMatch()) {
- CollectionsSearchResponse.Match match = new CollectionsSearchResponse.Match();
- match.setField("name");
- match.setSnippet(dto.getName());
- matches.add(match);
- }
-
- if (!matches.isEmpty()) {
- if (response.getMatches() == null) {
- response.setMatches(matches);
- } else {
- response.getMatches().addAll(matches);
- }
- }
- }
-
- private static Optional createHighlightMatch(
- String highlight, String fieldName) {
- if (!Strings.isNullOrEmpty(highlight) && HIGHLIGHT_PATTERN.matcher(highlight).matches()) {
- CollectionsSearchResponse.Match match = new CollectionsSearchResponse.Match();
- match.setField(fieldName);
- match.setSnippet(highlight);
- return Optional.of(match);
- }
-
- return Optional.empty();
- }
-}
diff --git a/registry-service/pom.xml b/registry-service/pom.xml
index 98afa9d98a..4880a4f578 100644
--- a/registry-service/pom.xml
+++ b/registry-service/pom.xml
@@ -54,6 +54,10 @@
org.gbif.vocabulary
vocabulary-rest-ws-client
+
+ org.gbif
+ gbif-parsers
+
diff --git a/registry-service/src/main/java/org/gbif/registry/service/collections/BaseCollectionEntityService.java b/registry-service/src/main/java/org/gbif/registry/service/collections/BaseCollectionEntityService.java
index 6a5d8a829b..b1f1c34fd4 100644
--- a/registry-service/src/main/java/org/gbif/registry/service/collections/BaseCollectionEntityService.java
+++ b/registry-service/src/main/java/org/gbif/registry/service/collections/BaseCollectionEntityService.java
@@ -14,7 +14,6 @@
package org.gbif.registry.service.collections;
import lombok.extern.slf4j.Slf4j;
-import org.elasticsearch.common.Strings;
import org.gbif.api.model.collections.Address;
import org.gbif.api.model.collections.Contact;
import org.gbif.api.model.collections.*;
@@ -33,7 +32,6 @@
import org.gbif.registry.events.collections.*;
import org.gbif.registry.persistence.mapper.*;
import org.gbif.registry.persistence.mapper.collections.*;
-import org.gbif.registry.persistence.mapper.collections.params.RangeParam;
import org.gbif.registry.security.SecurityContextCheck;
import org.gbif.registry.service.WithMyBatis;
import org.gbif.registry.service.collections.utils.IdentifierValidatorUtils;
@@ -57,14 +55,11 @@
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
-import java.util.regex.Matcher;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkArgument;
import static org.gbif.registry.security.UserRoles.*;
import static org.gbif.registry.service.collections.utils.MasterSourceUtils.*;
-import static org.gbif.registry.service.collections.utils.SearchUtils.INTEGER_RANGE;
-import static org.gbif.registry.service.collections.utils.SearchUtils.WILDCARD_SEARCH;
@Validated
@Slf4j
@@ -876,43 +871,4 @@ private void checkExistsNetworkEntity(
"Cannot set a deleted " + entityClass.getSimpleName() + " as master source");
}
}
-
- protected RangeParam parseIntegerRangeParameter(String param) {
- if (Strings.isNullOrEmpty(param)) {
- return null;
- }
-
- RangeParam rangeParam = new RangeParam();
- Matcher matcher = INTEGER_RANGE.matcher(param);
- if (matcher.matches()) {
- String lowerString = matcher.group(1);
- if (!lowerString.equals(WILDCARD_SEARCH)) {
- rangeParam.setLowerBound(Integer.valueOf(lowerString));
- }
-
- String higherString = matcher.group(2);
- if (!higherString.equals(WILDCARD_SEARCH)) {
- rangeParam.setHigherBound(Integer.valueOf(higherString));
- }
- } else {
- try {
- rangeParam.setExactValue(Integer.valueOf(param));
- } catch (Exception ex) {
- log.info("Invalid range {}", param, ex);
- }
- }
-
- return rangeParam;
- }
-
- protected List parseGbifRegion(SearchRequest searchRequest) {
- List countries = new ArrayList<>();
- if (searchRequest.getGbifRegion() != null && !searchRequest.getGbifRegion().isEmpty()) {
- countries.addAll(
- Arrays.stream(Country.values())
- .filter(c -> searchRequest.getGbifRegion().contains(c.getGbifRegion()))
- .collect(Collectors.toList()));
- }
- return countries;
- }
}
diff --git a/registry-service/src/main/java/org/gbif/registry/service/collections/CollectionsSearchService.java b/registry-service/src/main/java/org/gbif/registry/service/collections/CollectionsSearchService.java
new file mode 100644
index 0000000000..8c7ff4ae19
--- /dev/null
+++ b/registry-service/src/main/java/org/gbif/registry/service/collections/CollectionsSearchService.java
@@ -0,0 +1,418 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.gbif.registry.service.collections;
+
+import static org.gbif.registry.service.collections.utils.ParamUtils.parseGbifRegion;
+import static org.gbif.registry.service.collections.utils.ParamUtils.parseIntegerRangeParameter;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Strings;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import org.gbif.api.model.collections.request.CollectionDescriptorsSearchRequest;
+import org.gbif.api.model.collections.request.InstitutionSearchRequest;
+import org.gbif.api.model.collections.request.SearchRequest;
+import org.gbif.api.model.collections.search.BaseSearchResponse;
+import org.gbif.api.model.collections.search.CollectionSearchResponse;
+import org.gbif.api.model.collections.search.CollectionsFullSearchResponse;
+import org.gbif.api.model.collections.search.DescriptorMatch;
+import org.gbif.api.model.collections.search.Highlight;
+import org.gbif.api.model.collections.search.InstitutionSearchResponse;
+import org.gbif.api.model.common.paging.Pageable;
+import org.gbif.api.model.common.paging.PagingRequest;
+import org.gbif.api.model.common.paging.PagingResponse;
+import org.gbif.api.vocabulary.Country;
+import org.gbif.registry.domain.collections.TypeParam;
+import org.gbif.registry.persistence.mapper.collections.CollectionsSearchMapper;
+import org.gbif.registry.persistence.mapper.collections.dto.BaseSearchDto;
+import org.gbif.registry.persistence.mapper.collections.dto.CollectionSearchDto;
+import org.gbif.registry.persistence.mapper.collections.dto.InstitutionSearchDto;
+import org.gbif.registry.persistence.mapper.collections.dto.SearchDto;
+import org.gbif.registry.persistence.mapper.collections.params.DescriptorsParams;
+import org.gbif.registry.persistence.mapper.collections.params.FullTextSearchParams;
+import org.gbif.registry.persistence.mapper.collections.params.InstitutionListParams;
+import org.gbif.registry.persistence.mapper.collections.params.ListParams;
+import org.gbif.registry.service.collections.utils.Vocabularies;
+import org.gbif.vocabulary.client.ConceptClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/** Service to lookup GRSciColl institutions and collections. */
+@Service
+public class CollectionsSearchService {
+
+ private static final Pattern HIGHLIGHT_PATTERN = Pattern.compile(".*.+.*");
+
+ private final CollectionsSearchMapper searchMapper;
+ private final ConceptClient conceptClient;
+
+ @Autowired
+ public CollectionsSearchService(
+ CollectionsSearchMapper searchMapper, ConceptClient conceptClient) {
+ this.searchMapper = searchMapper;
+ this.conceptClient = conceptClient;
+ }
+
+ public List search(
+ String query,
+ boolean highlight,
+ TypeParam type,
+ Boolean displayOnNHCPortal,
+ Country country,
+ int limit) {
+ List dtos =
+ searchMapper.search(
+ FullTextSearchParams.builder()
+ .query(query)
+ .highlight(highlight)
+ .type(type != null ? type.name() : null)
+ .displayOnNHCPortal(displayOnNHCPortal)
+ .country(country)
+ .limit(limit)
+ .build());
+
+ // the query can return duplicates so we need an auxiliary map to filter duplicates
+ Map responsesMap = new HashMap<>();
+ List responses = new ArrayList<>();
+ dtos.forEach(
+ dto -> {
+ if (responsesMap.containsKey(dto.getKey())) {
+ CollectionsFullSearchResponse existing = responsesMap.get(dto.getKey());
+ if (highlight) {
+ addHighlights(existing, dto);
+ }
+ if (dto.getDescriptorKey() != null) {
+ existing.getDescriptorMatches().add(addDescriptorMatch(dto));
+ }
+ return;
+ }
+
+ CollectionsFullSearchResponse response = new CollectionsFullSearchResponse();
+ response.setType(dto.getType());
+ response.setCode(dto.getCode());
+ response.setKey(dto.getKey());
+ response.setName(dto.getName());
+ response.setDisplayOnNHCPortal(dto.isDisplayOnNHCPortal());
+ response.setCountry(dto.getCountry());
+ response.setMailingCountry(dto.getMailingCountry());
+
+ if (dto.getType().equals("collection")) {
+ response.setInstitutionKey(dto.getInstitutionKey());
+ response.setInstitutionCode(dto.getInstitutionCode());
+ response.setInstitutionName(dto.getInstitutionName());
+ }
+
+ if (dto.getDescriptorKey() != null) {
+ response.getDescriptorMatches().add(addDescriptorMatch(dto));
+ }
+
+ if (highlight) {
+ addHighlights(response, dto);
+ }
+
+ responses.add(response);
+ responsesMap.put(dto.getKey(), response);
+ });
+
+ return responses;
+ }
+
+ public PagingResponse searchInstitutions(
+ InstitutionSearchRequest searchRequest) {
+
+ Pageable page = searchRequest.getPage() == null ? new PagingRequest() : searchRequest.getPage();
+
+ Vocabularies.addChildrenConcepts(searchRequest, conceptClient);
+
+ InstitutionListParams.InstitutionListParamsBuilder listParamsBuilder =
+ InstitutionListParams.builder()
+ .types(searchRequest.getType())
+ .institutionalGovernances(searchRequest.getInstitutionalGovernance())
+ .disciplines(searchRequest.getDisciplines())
+ .institutionKeys(searchRequest.getInstitutionKeys());
+ buildCommonParams(listParamsBuilder, searchRequest);
+ InstitutionListParams listParams = listParamsBuilder.build();
+
+ List dtos = searchMapper.searchInstitutions(listParams);
+ List results =
+ dtos.stream()
+ .map(
+ dto -> {
+ InstitutionSearchResponse response = new InstitutionSearchResponse();
+ createCommonResponse(dto, response);
+ response.setTypes(dto.getTypes());
+ response.setInstitutionalGovernances(dto.getInstitutionalGovernances());
+ response.setDisciplines(dto.getDisciplines());
+ response.setLatitude(dto.getLatitude());
+ response.setLongitude(dto.getLongitude());
+ response.setFoundingDate(dto.getFoundingDate());
+ response.setNumberSpecimens(dto.getNumberSpecimens());
+ response.setOccurrenceCount(dto.getOccurrenceCount());
+ response.setTypeSpecimenCount(dto.getTypeSpecimenCount());
+
+ if (Boolean.TRUE.equals(searchRequest.getHl())) {
+ addHighlights(response, dto);
+ }
+
+ return response;
+ })
+ .collect(Collectors.toList());
+
+ return new PagingResponse<>(page, searchMapper.countInstitutions(listParams), results);
+ }
+
+ public PagingResponse searchCollections(
+ CollectionDescriptorsSearchRequest searchRequest) {
+
+ Pageable page = searchRequest.getPage() == null ? new PagingRequest() : searchRequest.getPage();
+
+ Set institutionKeys = new HashSet<>();
+ if (searchRequest.getInstitution() != null) {
+ institutionKeys.add(searchRequest.getInstitution());
+ }
+ if (searchRequest.getInstitutionKeys() != null) {
+ institutionKeys.addAll(searchRequest.getInstitutionKeys());
+ }
+
+ Vocabularies.addChildrenConcepts(searchRequest, conceptClient);
+
+ DescriptorsParams.DescriptorsParamsBuilder listParamsBuilder =
+ DescriptorsParams.builder()
+ .contentTypes(searchRequest.getContentTypes())
+ .preservationTypes(searchRequest.getPreservationTypes())
+ .accessionStatus(searchRequest.getAccessionStatus())
+ .personalCollection(searchRequest.getPersonalCollection())
+ .institutionKeys(new ArrayList<>(institutionKeys))
+ .usageName(searchRequest.getUsageName())
+ .usageKey(searchRequest.getUsageKey())
+ .usageRank(searchRequest.getUsageRank())
+ .taxonKey(searchRequest.getTaxonKey())
+ .descriptorCountry(searchRequest.getDescriptorCountry())
+ .individualCount(parseIntegerRangeParameter(searchRequest.getIndividualCount()))
+ .identifiedBy(searchRequest.getIdentifiedBy())
+ .dateIdentifiedBefore(
+ searchRequest.getDateIdentified() != null
+ ? searchRequest.getDateIdentified().lowerEndpoint()
+ : null)
+ .dateIdentifiedFrom(
+ searchRequest.getDateIdentified() != null
+ ? searchRequest.getDateIdentified().upperEndpoint()
+ : null)
+ .typeStatus(searchRequest.getTypeStatus())
+ .recordedBy(searchRequest.getRecordedBy())
+ .discipline(searchRequest.getDiscipline())
+ .objectClassification(searchRequest.getObjectClassification())
+ .issues(searchRequest.getIssue());
+ buildCommonParams(listParamsBuilder, searchRequest);
+ DescriptorsParams listParams = listParamsBuilder.build();
+
+ List dtos = searchMapper.searchCollections(listParams);
+ Map responsesMap = new HashMap<>();
+ List results = new ArrayList<>();
+ dtos.stream()
+ .forEach(
+ dto -> {
+ if (responsesMap.containsKey(dto.getKey())) {
+ CollectionSearchResponse existing = responsesMap.get(dto.getKey());
+ if (Boolean.TRUE.equals(listParams.getHighlight())) {
+ addHighlights(existing, dto);
+ }
+ if (isCollectionDescriptorResult(dto, listParams)) {
+ existing.getDescriptorMatches().add(addDescriptorMatch(dto));
+ }
+ return;
+ }
+
+ CollectionSearchResponse response = new CollectionSearchResponse();
+ responsesMap.put(dto.getKey(), response);
+ results.add(response);
+
+ createCommonResponse(dto, response);
+ response.setContentTypes(dto.getContentTypes());
+ response.setPersonalCollection(dto.isPersonalCollection());
+ response.setPreservationTypes(dto.getPreservationTypes());
+ response.setAccessionStatus(dto.getAccessionStatus());
+ response.setInstitutionKey(dto.getInstitutionKey());
+ response.setInstitutionName(dto.getInstitutionName());
+ response.setInstitutionCode(dto.getInstitutionCode());
+ response.setNumberSpecimens(dto.getNumberSpecimens());
+ response.setTaxonomicCoverage(dto.getTaxonomicCoverage());
+ response.setGeographicCoverage(dto.getGeographicCoverage());
+ response.setDepartment(dto.getDepartment());
+ response.setDivision(dto.getDivision());
+ response.setDisplayOnNHCPortal(dto.isDisplayOnNHCPortal());
+ response.setOccurrenceCount(dto.getOccurrenceCount());
+ response.setTypeSpecimenCount(dto.getTypeSpecimenCount());
+
+ if (isCollectionDescriptorResult(dto, listParams)) {
+ response.getDescriptorMatches().add(addDescriptorMatch(dto));
+ }
+
+ if (Boolean.TRUE.equals(searchRequest.getHl())) {
+ addHighlights(response, dto);
+ }
+ });
+
+ return new PagingResponse<>(page, searchMapper.countCollections(listParams), results);
+ }
+
+ private static boolean isCollectionDescriptorResult(
+ CollectionSearchDto dto, DescriptorsParams params) {
+ return dto.getDescriptorKey() != null
+ && (dto.getQueryDescriptorRank() != null && dto.getQueryDescriptorRank() > 0
+ || params.descriptorSearchWithoutQuery());
+ }
+
+ private static DescriptorMatch addDescriptorMatch(SearchDto dto) {
+ DescriptorMatch descriptorMatch = new DescriptorMatch();
+ descriptorMatch.setKey(dto.getDescriptorKey());
+ descriptorMatch.setDescriptorGroupKey(dto.getDescriptorGroupKey());
+ descriptorMatch.setUsageName(dto.getDescriptorUsageName());
+ descriptorMatch.setUsageKey(dto.getDescriptorUsageKey());
+ descriptorMatch.setUsageRank(dto.getDescriptorUsageRank());
+ descriptorMatch.setCountry(dto.getDescriptorCountry());
+ descriptorMatch.setIndividualCount(dto.getDescriptorIndividualCount());
+ descriptorMatch.setIdentifiedBy(dto.getDescriptorIdentifiedBy());
+ descriptorMatch.setDateIdentified(dto.getDescriptorDateIdentified());
+ descriptorMatch.setTypeStatus(dto.getDescriptorTypeStatus());
+ descriptorMatch.setRecordedBy(dto.getDescriptorRecordedBy());
+ descriptorMatch.setDiscipline(dto.getDescriptorDiscipline());
+ descriptorMatch.setObjectClassification(dto.getDescriptorObjectClassification());
+ descriptorMatch.setIssues(dto.getDescriptorIssues());
+ return descriptorMatch;
+ }
+
+ private void buildCommonParams(
+ ListParams.ListParamsBuilder listParams, SearchRequest searchRequest) {
+ String query =
+ searchRequest.getQ() != null
+ ? Strings.emptyToNull(CharMatcher.WHITESPACE.trimFrom(searchRequest.getQ()))
+ : searchRequest.getQ();
+
+ listParams
+ .query(query)
+ .code(searchRequest.getCode())
+ .name(searchRequest.getName())
+ .alternativeCode(searchRequest.getAlternativeCode())
+ .countries(searchRequest.getCountry())
+ .regionCountries(parseGbifRegion(searchRequest))
+ .city(searchRequest.getCity())
+ .fuzzyName(searchRequest.getFuzzyName())
+ .active(searchRequest.getActive())
+ .masterSourceType(searchRequest.getMasterSourceType())
+ .numberSpecimens(parseIntegerRangeParameter(searchRequest.getNumberSpecimens()))
+ .displayOnNHCPortal(searchRequest.getDisplayOnNHCPortal())
+ .occurrenceCount(parseIntegerRangeParameter(searchRequest.getOccurrenceCount()))
+ .typeSpecimenCount(parseIntegerRangeParameter(searchRequest.getTypeSpecimenCount()))
+ .sortBy(searchRequest.getSortBy())
+ .sortOrder(searchRequest.getSortOrder())
+ .highlight(searchRequest.getHl())
+ .page(searchRequest.getPage());
+ }
+
+ private void createCommonResponse(BaseSearchDto dto, BaseSearchResponse response) {
+ response.setKey(dto.getKey());
+ response.setCode(dto.getCode());
+ response.setName(dto.getName());
+ response.setDescription(dto.getDescription());
+ response.setActive(dto.isActive());
+ response.setCountry(dto.getCountry());
+ response.setMailingCountry(dto.getMailingCountry());
+ response.setCity(dto.getCity());
+ response.setMailingCity(dto.getMailingCity());
+ response.setAlternativeCodes(dto.getAlternativeCodes());
+ response.setDisplayOnNHCPortal(dto.isDisplayOnNHCPortal());
+ response.setFeaturedImageUrl(dto.getFeaturedImageUrl());
+ response.setFeaturedImageLicense(dto.getFeaturedImageLicense());
+ response.setFeaturedImageAttribution(dto.getFeaturedImageAttribution());
+ }
+
+ private void addHighlights(BaseSearchResponse response, BaseSearchDto dto) {
+ Set highlights = new HashSet<>();
+ createHighlightMatch(dto.getCodeHighlight(), "code").ifPresent(highlights::add);
+ createHighlightMatch(dto.getDescriptionHighlight(), "description").ifPresent(highlights::add);
+ createHighlightMatch(dto.getAlternativeCodesHighlight(), "alternativeCode")
+ .ifPresent(highlights::add);
+ createHighlightMatch(dto.getAddressHighlight(), "address").ifPresent(highlights::add);
+ createHighlightMatch(dto.getCityHighlight(), "city").ifPresent(highlights::add);
+ createHighlightMatch(dto.getProvinceHighlight(), "province").ifPresent(highlights::add);
+ createHighlightMatch(dto.getCountryHighlight(), "country").ifPresent(highlights::add);
+ createHighlightMatch(dto.getMailAddressHighlight(), "mailingAddress")
+ .ifPresent(highlights::add);
+ createHighlightMatch(dto.getMailCityHighlight(), "mailingCity").ifPresent(highlights::add);
+ createHighlightMatch(dto.getMailProvinceHighlight(), "mailingProvince")
+ .ifPresent(highlights::add);
+ createHighlightMatch(dto.getMailCountryHighlight(), "mailingCountry")
+ .ifPresent(highlights::add);
+ createHighlightMatch(dto.getDescriptorUsageNameHighlight(), "descriptor.usageName")
+ .ifPresent(highlights::add);
+ createHighlightMatch(dto.getDescriptorCountryHighlight(), "descriptor.country")
+ .ifPresent(highlights::add);
+ createHighlightMatch(dto.getDescriptorIdentifiedByHighlight(), "descriptor.identifiedBy")
+ .ifPresent(highlights::add);
+ createHighlightMatch(dto.getDescriptorTypeStatusHighlight(), "descriptor.typeStatus")
+ .ifPresent(highlights::add);
+ createHighlightMatch(dto.getDescriptorRecordedByHighlight(), "descriptor.recordedBy")
+ .ifPresent(highlights::add);
+ createHighlightMatch(dto.getDescriptorDisciplineHighlight(), "descriptor.discipline")
+ .ifPresent(highlights::add);
+ createHighlightMatch(
+ dto.getDescriptorObjectClassificationHighlight(), "descriptor.objectClassification")
+ .ifPresent(highlights::add);
+ createHighlightMatch(dto.getDescriptorIssuesHighlight(), "descriptor.issues")
+ .ifPresent(highlights::add);
+ createHighlightMatch(dto.getDescriptorGroupTitleHighlight(), "descriptorGroup.title")
+ .ifPresent(highlights::add);
+ createHighlightMatch(dto.getDescriptorGroupDescriptionHighlight(), "descriptorGroup.description")
+ .ifPresent(highlights::add);
+
+ Optional nameMatch = createHighlightMatch(dto.getNameHighlight(), "name");
+ if (nameMatch.isPresent()) {
+ highlights.add(nameMatch.get());
+ } else if (dto.isSimilarityMatch()) {
+ Highlight highlight = new Highlight();
+ highlight.setField("name");
+ highlight.setSnippet(dto.getName());
+ highlights.add(highlight);
+ }
+
+ if (!highlights.isEmpty()) {
+ if (response.getHighlights() == null) {
+ response.setHighlights(highlights);
+ } else {
+ response.getHighlights().addAll(highlights);
+ }
+ }
+ }
+
+ private static Optional createHighlightMatch(String highlightText, String fieldName) {
+ if (!Strings.isNullOrEmpty(highlightText)
+ && HIGHLIGHT_PATTERN.matcher(highlightText).matches()) {
+ Highlight highlight = new Highlight();
+ highlight.setField(fieldName);
+ highlight.setSnippet(highlightText);
+ return Optional.of(highlight);
+ }
+
+ return Optional.empty();
+ }
+}
diff --git a/registry-service/src/main/java/org/gbif/registry/service/collections/DefaultCollectionService.java b/registry-service/src/main/java/org/gbif/registry/service/collections/DefaultCollectionService.java
index 038e80c62e..92f18c9ec6 100644
--- a/registry-service/src/main/java/org/gbif/registry/service/collections/DefaultCollectionService.java
+++ b/registry-service/src/main/java/org/gbif/registry/service/collections/DefaultCollectionService.java
@@ -13,8 +13,21 @@
*/
package org.gbif.registry.service.collections;
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.gbif.registry.security.UserRoles.*;
+import static org.gbif.registry.service.collections.utils.ParamUtils.parseGbifRegion;
+import static org.gbif.registry.service.collections.utils.ParamUtils.parseIntegerRangeParameter;
+
import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
+import java.util.*;
+import java.util.stream.Collectors;
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import javax.validation.Valid;
+import javax.validation.Validator;
+import javax.validation.constraints.NotNull;
+import javax.validation.groups.Default;
import org.gbif.api.model.collections.Collection;
import org.gbif.api.model.collections.Contact;
import org.gbif.api.model.collections.MasterSourceMetadata;
@@ -35,7 +48,7 @@
import org.gbif.registry.persistence.mapper.*;
import org.gbif.registry.persistence.mapper.collections.*;
import org.gbif.registry.persistence.mapper.collections.dto.CollectionDto;
-import org.gbif.registry.persistence.mapper.collections.params.CollectionSearchParams;
+import org.gbif.registry.persistence.mapper.collections.params.CollectionListParams;
import org.gbif.registry.service.WithMyBatis;
import org.gbif.registry.service.collections.converters.CollectionConverter;
import org.gbif.registry.service.collections.utils.LatimerCoreConverter;
@@ -48,18 +61,6 @@
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestParam;
-import javax.validation.ConstraintViolation;
-import javax.validation.ConstraintViolationException;
-import javax.validation.Valid;
-import javax.validation.Validator;
-import javax.validation.constraints.NotNull;
-import javax.validation.groups.Default;
-import java.util.*;
-import java.util.stream.Collectors;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.gbif.registry.security.UserRoles.*;
-
@Validated
@Service
public class DefaultCollectionService extends BaseCollectionEntityService
@@ -142,7 +143,7 @@ public PagingResponse listAsLatimerCore(CollectionSearchRequest sea
private PagingResponse listInternal(
CollectionSearchRequest searchRequest, boolean deleted) {
if (searchRequest == null) {
- searchRequest = new CollectionSearchRequest();
+ searchRequest = CollectionSearchRequest.builder().build();
}
Pageable page = searchRequest.getPage() == null ? new PagingRequest() : searchRequest.getPage();
@@ -162,8 +163,8 @@ private PagingResponse listInternal(
Vocabularies.addChildrenConcepts(searchRequest, conceptClient);
- CollectionSearchParams params =
- CollectionSearchParams.builder()
+ CollectionListParams params =
+ CollectionListParams.builder()
.query(query)
.code(searchRequest.getCode())
.name(searchRequest.getName())
diff --git a/registry-service/src/main/java/org/gbif/registry/service/collections/DefaultInstitutionService.java b/registry-service/src/main/java/org/gbif/registry/service/collections/DefaultInstitutionService.java
index c1835cf9c5..a0acb2e296 100644
--- a/registry-service/src/main/java/org/gbif/registry/service/collections/DefaultInstitutionService.java
+++ b/registry-service/src/main/java/org/gbif/registry/service/collections/DefaultInstitutionService.java
@@ -13,8 +13,23 @@
*/
package org.gbif.registry.service.collections;
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.gbif.registry.security.UserRoles.*;
+import static org.gbif.registry.service.collections.utils.ParamUtils.parseGbifRegion;
+import static org.gbif.registry.service.collections.utils.ParamUtils.parseIntegerRangeParameter;
+
import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import javax.validation.Valid;
+import javax.validation.Validator;
+import javax.validation.constraints.NotNull;
+import javax.validation.groups.Default;
import org.gbif.api.model.collections.Contact;
import org.gbif.api.model.collections.Institution;
import org.gbif.api.model.collections.MasterSourceMetadata;
@@ -35,7 +50,7 @@
import org.gbif.registry.persistence.mapper.*;
import org.gbif.registry.persistence.mapper.collections.*;
import org.gbif.registry.persistence.mapper.collections.dto.InstitutionGeoJsonDto;
-import org.gbif.registry.persistence.mapper.collections.params.InstitutionSearchParams;
+import org.gbif.registry.persistence.mapper.collections.params.InstitutionListParams;
import org.gbif.registry.service.WithMyBatis;
import org.gbif.registry.service.collections.converters.InstitutionConverter;
import org.gbif.registry.service.collections.utils.LatimerCoreConverter;
@@ -51,20 +66,6 @@
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestParam;
-import javax.validation.ConstraintViolation;
-import javax.validation.ConstraintViolationException;
-import javax.validation.Valid;
-import javax.validation.Validator;
-import javax.validation.constraints.NotNull;
-import javax.validation.groups.Default;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
-import java.util.stream.Collectors;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.gbif.registry.security.UserRoles.*;
-
@Validated
@Service
public class DefaultInstitutionService extends BaseCollectionEntityService
@@ -168,27 +169,27 @@ public void updateFromLatimerCore(@NotNull @Valid OrganisationalUnit organisatio
private PagingResponse listInternal(
InstitutionSearchRequest searchRequest, boolean deleted) {
if (searchRequest == null) {
- searchRequest = new InstitutionSearchRequest();
+ searchRequest = InstitutionSearchRequest.builder().build();
}
Pageable page = searchRequest.getPage() == null ? new PagingRequest() : searchRequest.getPage();
Vocabularies.addChildrenConcepts(searchRequest, conceptClient);
- InstitutionSearchParams params = buildSearchParams(searchRequest, deleted, page);
+ InstitutionListParams params = buildSearchParams(searchRequest, deleted, page);
long total = institutionMapper.count(params);
return new PagingResponse<>(page, total, institutionMapper.list(params));
}
- private InstitutionSearchParams buildSearchParams(
+ private InstitutionListParams buildSearchParams(
InstitutionSearchRequest searchRequest, boolean deleted, Pageable page) {
String query =
searchRequest.getQ() != null
? Strings.emptyToNull(CharMatcher.WHITESPACE.trimFrom(searchRequest.getQ()))
: searchRequest.getQ();
- return InstitutionSearchParams.builder()
+ return InstitutionListParams.builder()
.query(query)
.code(searchRequest.getCode())
.name(searchRequest.getName())
diff --git a/registry-service/src/main/java/org/gbif/registry/service/collections/descriptors/DefaultDescriptorService.java b/registry-service/src/main/java/org/gbif/registry/service/collections/descriptors/DefaultDescriptorService.java
new file mode 100644
index 0000000000..943de9e070
--- /dev/null
+++ b/registry-service/src/main/java/org/gbif/registry/service/collections/descriptors/DefaultDescriptorService.java
@@ -0,0 +1,431 @@
+package org.gbif.registry.service.collections.descriptors;
+
+import static org.gbif.api.util.GrSciCollUtils.*;
+import static org.gbif.registry.service.collections.utils.ParamUtils.parseIntegerRangeParameter;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.opencsv.CSVParser;
+import com.opencsv.CSVParserBuilder;
+import com.opencsv.CSVReader;
+import com.opencsv.CSVReaderBuilder;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.stream.Collectors;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import lombok.SneakyThrows;
+import org.gbif.api.model.collections.Collection;
+import org.gbif.api.model.collections.descriptors.Descriptor;
+import org.gbif.api.model.collections.descriptors.DescriptorGroup;
+import org.gbif.api.model.collections.request.DescriptorGroupSearchRequest;
+import org.gbif.api.model.collections.request.DescriptorSearchRequest;
+import org.gbif.api.model.common.export.ExportFormat;
+import org.gbif.api.model.common.paging.Pageable;
+import org.gbif.api.model.common.paging.PagingRequest;
+import org.gbif.api.model.common.paging.PagingResponse;
+import org.gbif.api.service.collections.CollectionService;
+import org.gbif.api.service.collections.DescriptorsService;
+import org.gbif.api.vocabulary.Country;
+import org.gbif.api.vocabulary.collections.MasterSourceType;
+import org.gbif.checklistbank.ws.client.NubResourceClient;
+import org.gbif.dwc.terms.DwcTerm;
+import org.gbif.registry.events.EventManager;
+import org.gbif.registry.events.collections.EventType;
+import org.gbif.registry.events.collections.SubEntityCollectionEvent;
+import org.gbif.registry.persistence.mapper.collections.DescriptorsMapper;
+import org.gbif.registry.persistence.mapper.collections.dto.DescriptorDto;
+import org.gbif.registry.persistence.mapper.collections.dto.VerbatimDto;
+import org.gbif.registry.persistence.mapper.collections.params.DescriptorGroupParams;
+import org.gbif.registry.persistence.mapper.collections.params.DescriptorParams;
+import org.gbif.registry.service.collections.batch.FileParsingUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
+
+@Validated
+@Service
+public class DefaultDescriptorService implements DescriptorsService {
+
+ private final NubResourceClient nubResourceClient;
+ private final DescriptorsMapper descriptorsMapper;
+ private final EventManager eventManager;
+ private final CollectionService collectionService;
+
+ @Autowired
+ public DefaultDescriptorService(
+ NubResourceClient nubResourceClient,
+ DescriptorsMapper descriptorsMapper,
+ EventManager eventManager,
+ CollectionService collectionService) {
+ this.nubResourceClient = nubResourceClient;
+ this.descriptorsMapper = descriptorsMapper;
+ this.eventManager = eventManager;
+ this.collectionService = collectionService;
+ }
+
+ @SneakyThrows
+ @Transactional
+ @Override
+ public long createDescriptorGroup(
+ @NotNull @Valid byte[] descriptorGroupFile,
+ @NotNull ExportFormat format,
+ @NotNull String title,
+ String description,
+ @NotNull UUID collectionKey) {
+ Objects.requireNonNull(descriptorGroupFile);
+ Preconditions.checkArgument(descriptorGroupFile.length > 0);
+ Objects.requireNonNull(collectionKey);
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(title));
+
+ final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ final String username = authentication.getName();
+
+ DescriptorGroup descriptorGroup = new DescriptorGroup();
+ descriptorGroup.setTitle(title);
+ descriptorGroup.setDescription(description);
+ descriptorGroup.setCreatedBy(username);
+ descriptorGroup.setModifiedBy(username);
+ descriptorGroup.setCollectionKey(collectionKey);
+ descriptorsMapper.createDescriptorGroup(descriptorGroup);
+
+ importDescriptorsFile(descriptorGroupFile, format, descriptorGroup.getKey());
+
+ eventManager.post(
+ SubEntityCollectionEvent.newInstance(
+ collectionKey,
+ Collection.class,
+ DescriptorGroup.class,
+ descriptorGroup.getKey(),
+ EventType.CREATE));
+
+ return descriptorGroup.getKey();
+ }
+
+ private void importDescriptorsFile(
+ @NotNull @Valid byte[] descriptorFile, ExportFormat format, long descriptorGroupKey)
+ throws IOException {
+ // csv options
+ CSVParser csvParser = new CSVParserBuilder().withSeparator(format.getDelimiter()).build();
+
+ Map headersByIndex = new HashMap<>();
+ Map headersByName = new HashMap<>();
+ try (CSVReader csvReader =
+ new CSVReaderBuilder(
+ new BufferedReader(new InputStreamReader(new ByteArrayInputStream(descriptorFile))))
+ .withCSVParser(csvParser)
+ .build()) {
+ // extract headers
+ String[] headers = csvReader.readNextSilently();
+ for (int i = 0; i < headers.length; i++) {
+ headersByIndex.put(i, headers[i]);
+ headersByName.put(headers[i].toLowerCase(), i);
+ }
+
+ String[] values;
+ while ((values = csvReader.readNextSilently()) != null) {
+ if (values.length == 0) {
+ continue;
+ }
+
+ values = FileParsingUtils.normalizeValues(headersByIndex.entrySet().size(), values);
+
+ DescriptorDto descriptorDto = new DescriptorDto();
+ descriptorDto.setDescriptorGroupKey(descriptorGroupKey);
+
+ // taxonomy
+ InterpretedResult taxonomyResult =
+ Interpreter.interpretTaxonomy(values, headersByName, nubResourceClient);
+ if (taxonomyResult.getResult() != null) {
+ descriptorDto.setUsageKey(taxonomyResult.getResult().getUsageKey());
+ descriptorDto.setUsageRank(taxonomyResult.getResult().getUsageRank());
+ descriptorDto.setUsageName(taxonomyResult.getResult().getUsageName());
+ descriptorDto.setTaxonKeys(taxonomyResult.getResult().getTaxonKeys());
+ descriptorDto.setTaxonClassification(taxonomyResult.getResult().getTaxonClassification());
+ }
+ addIssues(descriptorDto, taxonomyResult);
+
+ // country
+ InterpretedResult countryResult =
+ Interpreter.interpretCountry(values, headersByName);
+ setResult(descriptorDto, countryResult, DescriptorDto::setCountry);
+
+ // individual count
+ InterpretedResult individualCountResult =
+ Interpreter.interpretIndividualCount(values, headersByName);
+ setResult(descriptorDto, individualCountResult, DescriptorDto::setIndividualCount);
+
+ // identifiedBy
+ InterpretedResult> identifiedByResult =
+ Interpreter.interpretStringList(values, headersByName, DwcTerm.identifiedBy);
+ setResult(descriptorDto, identifiedByResult, DescriptorDto::setIdentifiedBy);
+
+ // dateIdentified
+ InterpretedResult dateIdentifiedResult =
+ Interpreter.interpretDateIdentified(values, headersByName);
+ setResult(descriptorDto, dateIdentifiedResult, DescriptorDto::setDateIdentified);
+
+ // TypeStatus
+ InterpretedResult> typeStatusResult =
+ Interpreter.interpretTypeStatus(values, headersByName);
+ setResult(descriptorDto, typeStatusResult, DescriptorDto::setTypeStatus);
+
+ // recordedBy
+ InterpretedResult> recordedByResult =
+ Interpreter.interpretStringList(values, headersByName, DwcTerm.recordedBy);
+ setResult(descriptorDto, recordedByResult, DescriptorDto::setRecordedBy);
+
+ // TODO: create ltc terms??
+ // discipline
+ InterpretedResult disciplineResult =
+ Interpreter.interpretString(values, headersByName, "ltc:discipline");
+ setResult(descriptorDto, disciplineResult, DescriptorDto::setDiscipline);
+
+ // objectClassification
+ InterpretedResult objectClassificationResult =
+ Interpreter.interpretString(values, headersByName, "ltc:objectClassificationName");
+ setResult(
+ descriptorDto, objectClassificationResult, DescriptorDto::setObjectClassificationName);
+
+ descriptorsMapper.createDescriptor(descriptorDto);
+
+ // verbatim fields
+ for (int i = 0; i < values.length; i++) {
+ descriptorsMapper.createVerbatim(
+ descriptorDto.getKey(), headersByIndex.get(i), values[i]);
+ }
+ }
+ }
+ }
+
+ private void setResult(
+ DescriptorDto descriptorDto,
+ InterpretedResult result,
+ BiConsumer setter) {
+ setter.accept(descriptorDto, result.getResult());
+ addIssues(descriptorDto, result);
+ }
+
+ private static void addIssues(DescriptorDto descriptorDto, InterpretedResult result) {
+ if (descriptorDto.getIssues() == null) {
+ descriptorDto.setIssues(new ArrayList<>());
+ }
+ if (result.getIssues() != null) {
+ descriptorDto.getIssues().addAll(result.getIssues());
+ }
+ }
+
+ @Override
+ public void deleteDescriptorGroup(@NotNull long key) {
+ DescriptorGroup descriptorGroup = descriptorsMapper.getDescriptorGroup(key);
+ Preconditions.checkArgument(
+ descriptorGroup != null, "Descriptor group not found for key " + key);
+
+ if (isIHDescriptorGroup(key, descriptorGroup.getCollectionKey())) {
+ // can't delete a descriptor group that comes from IH
+ return;
+ }
+
+ descriptorsMapper.deleteDescriptorGroup(key);
+
+ eventManager.post(
+ SubEntityCollectionEvent.newInstance(
+ descriptorGroup.getCollectionKey(),
+ Collection.class,
+ DescriptorGroup.class,
+ key,
+ EventType.DELETE));
+ }
+
+ @Override
+ public DescriptorGroup getDescriptorGroup(@NotNull long key) {
+ return descriptorsMapper.getDescriptorGroup(key);
+ }
+
+ @SneakyThrows
+ @Transactional
+ @Override
+ public void updateDescriptorGroup(
+ @NotNull long descriptorGroupKey,
+ @NotNull byte[] descriptorGroupFile,
+ @NotNull ExportFormat format,
+ @NotNull String title,
+ String description) {
+ Objects.requireNonNull(descriptorGroupFile);
+ Preconditions.checkArgument(descriptorGroupFile.length > 0);
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(title));
+
+ final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ final String username = authentication.getName();
+
+ DescriptorGroup descriptorGroup = descriptorsMapper.getDescriptorGroup(descriptorGroupKey);
+
+ if (isIHDescriptorGroup(descriptorGroupKey, descriptorGroup.getCollectionKey())) {
+ // can't update a descriptor group that comes from IH
+ return;
+ }
+
+ descriptorGroup.setTitle(title);
+ descriptorGroup.setDescription(description);
+ descriptorGroup.setModifiedBy(username);
+ descriptorsMapper.updateDescriptorGroup(descriptorGroup);
+
+ // remove descriptors
+ descriptorsMapper.deleteDescriptors(descriptorGroup.getKey());
+
+ // reimport the file
+ importDescriptorsFile(descriptorGroupFile, format, descriptorGroup.getKey());
+
+ eventManager.post(
+ SubEntityCollectionEvent.newInstance(
+ descriptorGroup.getCollectionKey(),
+ Collection.class,
+ DescriptorGroup.class,
+ descriptorGroupKey,
+ EventType.UPDATE));
+ }
+
+ private boolean isIHDescriptorGroup(long descriptorGroupKey, UUID collectionKey) {
+ Collection collection = collectionService.get(collectionKey);
+ List ihDescriptorGroups =
+ collection.getMachineTags().stream()
+ .filter(
+ mt ->
+ mt.getNamespace().equals(IH_NS)
+ && (mt.getName().equals(COLL_SUMMARY_MT)
+ || mt.getName().equals(COLLECTORS_MT))
+ && mt.getValue() != null)
+ .map(mt -> Long.parseLong(mt.getValue()))
+ .collect(Collectors.toList());
+
+ return collection.getMasterSource().equals(MasterSourceType.IH)
+ && ihDescriptorGroups.contains(descriptorGroupKey);
+ }
+
+ @Override
+ public PagingResponse listDescriptorGroups(
+ @NotNull UUID collectionKey, DescriptorGroupSearchRequest searchRequest) {
+ Objects.requireNonNull(collectionKey);
+ if (searchRequest == null) {
+ searchRequest = DescriptorGroupSearchRequest.builder().build();
+ }
+
+ Pageable page = searchRequest.getPage() == null ? new PagingRequest() : searchRequest.getPage();
+ String query =
+ searchRequest.getQ() != null
+ ? Strings.emptyToNull(CharMatcher.WHITESPACE.trimFrom(searchRequest.getQ()))
+ : searchRequest.getQ();
+
+ DescriptorGroupParams params =
+ DescriptorGroupParams.builder()
+ .query(query)
+ .collectionKey(collectionKey)
+ .title(searchRequest.getTitle())
+ .description(searchRequest.getDescription())
+ .deleted(searchRequest.getDeleted())
+ .page(page)
+ .build();
+
+ return new PagingResponse<>(
+ page,
+ descriptorsMapper.countDescriptorGroups(params),
+ descriptorsMapper.listDescriptorGroups(params));
+ }
+
+ @Override
+ public Descriptor getDescriptor(@NotNull long key) {
+ return convertRecordDto(descriptorsMapper.getDescriptor(key));
+ }
+
+ @Override
+ public PagingResponse listDescriptors(DescriptorSearchRequest searchRequest) {
+ if (searchRequest == null) {
+ searchRequest = DescriptorSearchRequest.builder().build();
+ }
+
+ DescriptorParams params = createDescriptorParams(searchRequest);
+ List dtos = descriptorsMapper.listDescriptors(params);
+ List results =
+ dtos.stream().map(DefaultDescriptorService::convertRecordDto).collect(Collectors.toList());
+
+ return new PagingResponse<>(
+ params.getPage(), descriptorsMapper.countDescriptors(params), results);
+ }
+
+ private DescriptorParams createDescriptorParams(DescriptorSearchRequest searchRequest) {
+ Pageable page = searchRequest.getPage() == null ? new PagingRequest() : searchRequest.getPage();
+ String query =
+ searchRequest.getQ() != null
+ ? Strings.emptyToNull(CharMatcher.WHITESPACE.trimFrom(searchRequest.getQ()))
+ : searchRequest.getQ();
+
+ return DescriptorParams.builder()
+ .query(query)
+ .descriptorGroupKey(searchRequest.getDescriptorGroupKey())
+ .country(searchRequest.getCountry())
+ .dateIdentifiedBefore(searchRequest.getDateIdentifiedBefore())
+ .dateIdentifiedFrom(searchRequest.getDateIdentifiedFrom())
+ .discipline(searchRequest.getDiscipline())
+ .individualCount(parseIntegerRangeParameter(searchRequest.getIndividualCount()))
+ .usageKey(searchRequest.getUsageKey())
+ .usageName(searchRequest.getUsageName())
+ .usageRank(searchRequest.getUsageRank())
+ .taxonKey(searchRequest.getTaxonKey())
+ .objectClassification(searchRequest.getObjectClassification())
+ .recordedBy(searchRequest.getRecordedBy())
+ .identifiedBy(searchRequest.getIdentifiedBy())
+ .issues(searchRequest.getIssues())
+ .typeStatus(searchRequest.getTypeStatus())
+ .page(page)
+ .build();
+ }
+
+ @Override
+ public long countDescriptors(DescriptorSearchRequest searchRequest) {
+ DescriptorParams params = createDescriptorParams(searchRequest);
+ return descriptorsMapper.countDescriptors(params);
+ }
+
+ @Override
+ public Set getVerbatimNames(long descriptorGroupKey) {
+ List dtos = descriptorsMapper.getVerbatimNames(descriptorGroupKey);
+ return dtos.stream()
+ .sorted(Comparator.comparing(VerbatimDto::getKey))
+ .map(VerbatimDto::getFieldName)
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+ }
+
+ private static Descriptor convertRecordDto(DescriptorDto dto) {
+ Descriptor descriptorRecord = new Descriptor();
+ descriptorRecord.setKey(dto.getKey());
+ descriptorRecord.setRecordedBy(dto.getRecordedBy());
+ descriptorRecord.setDescriptorGroupKey(dto.getDescriptorGroupKey());
+ descriptorRecord.setCountry(dto.getCountry());
+ descriptorRecord.setDiscipline(dto.getDiscipline());
+ descriptorRecord.setIssues(dto.getIssues());
+ descriptorRecord.setDateIdentified(dto.getDateIdentified());
+ descriptorRecord.setIdentifiedBy(dto.getIdentifiedBy());
+ descriptorRecord.setIndividualCount(dto.getIndividualCount());
+ descriptorRecord.setObjectClassification(dto.getObjectClassificationName());
+ descriptorRecord.setTypeStatus(dto.getTypeStatus());
+ descriptorRecord.setUsageKey(dto.getUsageKey());
+ descriptorRecord.setUsageName(dto.getUsageName());
+ descriptorRecord.setUsageRank(dto.getUsageRank());
+ descriptorRecord.setTaxonClassification(dto.getTaxonClassification());
+
+ Map verbatim = new LinkedHashMap<>();
+ dto.getVerbatim().stream()
+ .sorted(Comparator.comparing(VerbatimDto::getKey))
+ .forEach(v -> verbatim.put(v.getFieldName(), v.getFieldValue()));
+ descriptorRecord.setVerbatim(verbatim);
+ return descriptorRecord;
+ }
+}
diff --git a/registry-service/src/main/java/org/gbif/registry/service/collections/descriptors/InterpretedResult.java b/registry-service/src/main/java/org/gbif/registry/service/collections/descriptors/InterpretedResult.java
new file mode 100644
index 0000000000..f211e607dd
--- /dev/null
+++ b/registry-service/src/main/java/org/gbif/registry/service/collections/descriptors/InterpretedResult.java
@@ -0,0 +1,18 @@
+package org.gbif.registry.service.collections.descriptors;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@Builder
+public class InterpretedResult {
+
+ T result;
+ List issues;
+
+ public static InterpretedResult empty() {
+ return new InterpretedResult<>(null, null);
+ }
+}
diff --git a/registry-service/src/main/java/org/gbif/registry/service/collections/descriptors/Interpreter.java b/registry-service/src/main/java/org/gbif/registry/service/collections/descriptors/Interpreter.java
new file mode 100644
index 0000000000..e04ec91b2b
--- /dev/null
+++ b/registry-service/src/main/java/org/gbif/registry/service/collections/descriptors/Interpreter.java
@@ -0,0 +1,388 @@
+package org.gbif.registry.service.collections.descriptors;
+
+import static org.gbif.api.vocabulary.Kingdom.INCERTAE_SEDIS;
+import static org.gbif.api.vocabulary.OccurrenceIssue.*;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.Range;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.temporal.TemporalAccessor;
+import java.util.*;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import lombok.AccessLevel;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.gbif.api.model.checklistbank.NameUsage;
+import org.gbif.api.model.checklistbank.NameUsageMatch;
+import org.gbif.api.v2.NameUsageMatch2;
+import org.gbif.api.v2.RankedName;
+import org.gbif.api.vocabulary.Country;
+import org.gbif.api.vocabulary.OccurrenceIssue;
+import org.gbif.api.vocabulary.Rank;
+import org.gbif.api.vocabulary.TypeStatus;
+import org.gbif.checklistbank.ws.client.NubResourceClient;
+import org.gbif.common.parsers.CountryParser;
+import org.gbif.common.parsers.NumberParser;
+import org.gbif.common.parsers.TypeStatusParser;
+import org.gbif.common.parsers.core.OccurrenceParseResult;
+import org.gbif.common.parsers.core.ParseResult;
+import org.gbif.common.parsers.date.MultiinputTemporalParser;
+import org.gbif.dwc.terms.DwcTerm;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class Interpreter {
+
+ private static final String DEFAULT_SEPARATOR = "\\|";
+ private static final LocalDate EARLIEST_DATE_IDENTIFIED = LocalDate.of(1753, 1, 1);
+ private static final Pattern INT_POSITIVE_PATTERN = Pattern.compile("(^\\d{1,10}$)");
+ private static final MultiinputTemporalParser temporalParser = MultiinputTemporalParser.create();
+ private static final CountryParser countryParser = CountryParser.getInstance();
+ private static final TypeStatusParser typeStatusParser = TypeStatusParser.getInstance();
+
+ public static InterpretedResult> interpretStringList(
+ String[] values, Map headersByName, DwcTerm term) {
+ if (values.length == 0) {
+ return InterpretedResult.empty();
+ }
+
+ List verbatimValue = extractListValue(values, headersByName, term);
+ if (verbatimValue == null || verbatimValue.isEmpty()) {
+ return InterpretedResult.empty();
+ }
+
+ return InterpretedResult.>builder().result(verbatimValue).build();
+ }
+
+ public static InterpretedResult interpretString(
+ String[] values, Map headersByName, DwcTerm term) {
+ return interpretString(values, headersByName, term.prefixedName());
+ }
+
+ public static InterpretedResult interpretString(
+ String[] values, Map headersByName, String fieldName) {
+ if (values.length == 0) {
+ return InterpretedResult.empty();
+ }
+
+ String verbatimValue = extractValue(values, headersByName, fieldName);
+ if (Strings.isNullOrEmpty(verbatimValue)) {
+ return InterpretedResult.empty();
+ }
+
+ return InterpretedResult.builder().result(verbatimValue).build();
+ }
+
+ public static InterpretedResult> interpretTypeStatus(
+ String[] values, Map headersByName) {
+ if (values.length == 0) {
+ return InterpretedResult.empty();
+ }
+
+ List verbatimValue = extractListValue(values, headersByName, DwcTerm.typeStatus);
+ if (verbatimValue == null || verbatimValue.isEmpty()) {
+ return InterpretedResult.empty();
+ }
+
+ List results = new ArrayList<>();
+ Set issues = new HashSet<>();
+ verbatimValue.forEach(
+ v -> {
+ ParseResult