diff --git a/annotation-client/src/main/java/eu/europeana/annotation/client/connection/AnnotationApiConnection.java b/annotation-client/src/main/java/eu/europeana/annotation/client/connection/AnnotationApiConnection.java index 2c6f806c1..29848fdaa 100644 --- a/annotation-client/src/main/java/eu/europeana/annotation/client/connection/AnnotationApiConnection.java +++ b/annotation-client/src/main/java/eu/europeana/annotation/client/connection/AnnotationApiConnection.java @@ -22,6 +22,7 @@ import eu.europeana.annotation.client.model.result.AnnotationSearchResults; import eu.europeana.annotation.client.model.result.WhitelistOperationResponse; import eu.europeana.annotation.definitions.model.Annotation; +import eu.europeana.annotation.definitions.model.search.Query; import eu.europeana.annotation.definitions.model.search.SearchProfiles; import eu.europeana.annotation.definitions.model.search.result.AnnotationPage; import eu.europeana.annotation.definitions.model.vocabulary.WebAnnotationFields; @@ -668,13 +669,13 @@ private String buildUrl(String query, String qf, String sort, String sortOrder, if (StringUtils.isNotEmpty(page)) { url += "&page=" + page; } else { - url += "&page=0"; + url += "&page=" + Query.DEFAULT_PAGE; } if (StringUtils.isNotEmpty(pageSize)) { url += "&pageSize=" + pageSize; } else { - url += "&pageSize=10"; + url += "&pageSize=" + Query.DEFAULT_PAGE_SIZE; } if (StringUtils.isNotEmpty(language)) { diff --git a/annotation-client/src/test/java/eu/europeana/annotation/client/integration/webanno/search/AnnotationSearchApiTest.java b/annotation-client/src/test/java/eu/europeana/annotation/client/integration/webanno/search/AnnotationSearchApiTest.java index f67cc7081..76c965af3 100644 --- a/annotation-client/src/test/java/eu/europeana/annotation/client/integration/webanno/search/AnnotationSearchApiTest.java +++ b/annotation-client/src/test/java/eu/europeana/annotation/client/integration/webanno/search/AnnotationSearchApiTest.java @@ -14,6 +14,7 @@ import eu.europeana.annotation.client.config.ClientConfiguration; import eu.europeana.annotation.client.integration.webanno.BaseWebAnnotationDataSetTest; import eu.europeana.annotation.definitions.model.Annotation; +import eu.europeana.annotation.definitions.model.search.Query; import eu.europeana.annotation.definitions.model.search.SearchProfiles; import eu.europeana.annotation.definitions.model.search.result.AnnotationPage; import eu.europeana.annotation.definitions.model.vocabulary.WebAnnotationFields; @@ -76,10 +77,10 @@ public void testSearchAnnotationPaging() throws Exception { assertNotNull(annPg, "AnnotationPage must not be null"); //there might be old annotations of failing tests in the database assertTrue(TOTAL_IN_COLLECTION <= annPg.getTotalInCollection()); - assertEquals(annPg.getCurrentPage(), 0); + assertEquals(annPg.getCurrentPage(), Query.DEFAULT_PAGE); assertEquals(TOTAL_IN_PAGE, annPg.getTotalInPage()); assertEquals(TOTAL_IN_PAGE, annPg.getItems().getResultSize()); - assertNextPageNumber(annPg, 1); + assertNextPageNumber(annPg, Query.DEFAULT_PAGE + 1); // second page String npUri = annPg.getNextPageUri(); @@ -93,13 +94,13 @@ public void testSearchAnnotationPaging() throws Exception { String nextCurrentPageUri = secondAnnoPg.getNextPageUri(); log.debug("nextCurrentPageUri" + nextCurrentPageUri); assertNotNull(secondAnnoPg); - assertEquals(secondAnnoPg.getCurrentPage(), 1); - assertNextPageNumber(secondAnnoPg, 2); + assertEquals(secondAnnoPg.getCurrentPage(), Query.DEFAULT_PAGE + 1); + assertNextPageNumber(secondAnnoPg, Query.DEFAULT_PAGE + 2); assertEquals(TOTAL_IN_PAGE, secondAnnoPg.getTotalInPage()); assertEquals(TOTAL_IN_PAGE, secondAnnoPg.getItems().getResultSize()); // last page - int lastPageNum = (int)Math.ceil((TOTAL_IN_COLLECTION - 1) / TOTAL_IN_PAGE); + int lastPageNum = (int)Math.ceil(1.0 * TOTAL_IN_COLLECTION / TOTAL_IN_PAGE) + Query.DEFAULT_PAGE - 1; AnnotationPage lastPage = annSearchApi.searchAnnotations(VALUE_ALL, Integer.toString(lastPageNum), Integer.toString(TOTAL_IN_PAGE), null, null); assertEquals(lastPage.getCurrentPage(), lastPageNum); diff --git a/annotation-client/src/test/java/eu/europeana/annotation/client/integration/webanno/tag/DereferencedSemanticTaggingTest.java b/annotation-client/src/test/java/eu/europeana/annotation/client/integration/webanno/tag/DereferencedSemanticTaggingTest.java index 3b1055d6c..31e8e66af 100644 --- a/annotation-client/src/test/java/eu/europeana/annotation/client/integration/webanno/tag/DereferencedSemanticTaggingTest.java +++ b/annotation-client/src/test/java/eu/europeana/annotation/client/integration/webanno/tag/DereferencedSemanticTaggingTest.java @@ -15,6 +15,7 @@ import eu.europeana.annotation.definitions.model.Annotation; import eu.europeana.annotation.definitions.model.agent.impl.EdmAgent; import eu.europeana.annotation.definitions.model.body.impl.EdmAgentBody; +import eu.europeana.annotation.definitions.model.search.Query; import eu.europeana.annotation.definitions.model.search.SearchProfiles; import eu.europeana.annotation.definitions.model.search.result.AnnotationPage; import eu.europeana.annotation.definitions.model.vocabulary.MotivationTypes; @@ -133,7 +134,7 @@ public void testSearchDereferencedAnnotation() throws Exception { assertNotNull(annPg, "AnnotationPage must not be null"); //there must be annotations in database after initial insert in this test class assertTrue(0 <= annPg.getTotalInCollection()); - assertEquals(annPg.getCurrentPage(), 0); + assertEquals(annPg.getCurrentPage(), Query.DEFAULT_PAGE); for (Annotation foundAnnotation : annPg.getAnnotations()) { log.info(foundAnnotation.getIdentifier()); log.info(foundAnnotation.getBody().getHttpUri()); @@ -156,7 +157,7 @@ public void testSearchDereferencedAnnotationMultiLanguage() throws Exception { assertNotNull(annPg, "AnnotationPage must not be null"); //there must be annotations in database after initial insert in this test class assertTrue(0 <= annPg.getTotalInCollection()); - assertEquals(annPg.getCurrentPage(), 0); + assertEquals(annPg.getCurrentPage(), Query.DEFAULT_PAGE); for (Annotation foundAnnotation : annPg.getAnnotations()) { log.info(foundAnnotation.getIdentifier()); log.info(foundAnnotation.getBody().getHttpUri()); diff --git a/annotation-definitions/src/main/java/eu/europeana/annotation/definitions/model/search/Query.java b/annotation-definitions/src/main/java/eu/europeana/annotation/definitions/model/search/Query.java index 556c48f6f..9dbbf0082 100644 --- a/annotation-definitions/src/main/java/eu/europeana/annotation/definitions/model/search/Query.java +++ b/annotation-definitions/src/main/java/eu/europeana/annotation/definitions/model/search/Query.java @@ -45,7 +45,7 @@ public interface Query { /** * Default start parameter for Solr */ - public static final int DEFAULT_PAGE = 0; + public static final int DEFAULT_PAGE = 1; /** * Default number of items in the SERP */ diff --git a/annotation-solr/src/main/java/eu/europeana/annotation/solr/service/impl/SolrAnnotationUtils.java b/annotation-solr/src/main/java/eu/europeana/annotation/solr/service/impl/SolrAnnotationUtils.java index 74027f99f..50ea32013 100644 --- a/annotation-solr/src/main/java/eu/europeana/annotation/solr/service/impl/SolrAnnotationUtils.java +++ b/annotation-solr/src/main/java/eu/europeana/annotation/solr/service/impl/SolrAnnotationUtils.java @@ -56,16 +56,15 @@ protected SolrQuery toSolrQuery(Query searchQuery) { solrQuery.setFacetMinCount(1); solrQuery.setFacetLimit(SolrAnnotationConstants.DEFAULT_FACET_LIMIT); } - + if (searchQuery.getSort() != null) { - solrQuery.setSort(searchQuery.getSort(), SolrQuery.ORDER.valueOf(searchQuery.getSortOrder())); - } - - solrQuery.setFields(searchQuery.getViewFields()); + solrQuery.setSort(searchQuery.getSort(), SolrQuery.ORDER.valueOf(searchQuery.getSortOrder())); + } - // searchQuery.setStart(page>0? page -1: page); - // searchQuery.setRows(Math.min(rows, Query.MAX_PAGE_SIZE)); - solrQuery.setStart(searchQuery.getPageNr() * searchQuery.getPageSize()); + solrQuery.setFields(searchQuery.getViewFields()); + + final int solrPageNr = searchQuery.getPageNr() - Query.DEFAULT_PAGE; + solrQuery.setStart(solrPageNr * searchQuery.getPageSize()); solrQuery.setRows(searchQuery.getPageSize()); return solrQuery; diff --git a/annotation-tests/src/integration-test/java/eu/europeana/annotation/tests/utils/AnnotationTestUtils.java b/annotation-tests/src/integration-test/java/eu/europeana/annotation/tests/utils/AnnotationTestUtils.java index 82b7af111..5d1b1af24 100644 --- a/annotation-tests/src/integration-test/java/eu/europeana/annotation/tests/utils/AnnotationTestUtils.java +++ b/annotation-tests/src/integration-test/java/eu/europeana/annotation/tests/utils/AnnotationTestUtils.java @@ -25,6 +25,7 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import eu.europeana.annotation.definitions.model.Annotation; +import eu.europeana.annotation.definitions.model.search.Query; import eu.europeana.annotation.definitions.model.search.result.AnnotationPage; import eu.europeana.annotation.definitions.model.vocabulary.MotivationTypes; import eu.europeana.annotation.definitions.model.vocabulary.WebAnnotationFields; @@ -242,13 +243,13 @@ public static String buildUrl(String query, String[] qf, String[] facets, String if (StringUtils.isNotEmpty(page)) { url += "&page=" + page; } else { - url += "&page=0"; + url += "&page=" + Query.DEFAULT_PAGE; } if (StringUtils.isNotEmpty(pageSize)) { url += "&pageSize=" + pageSize; } else { - url += "&pageSize=10"; + url += "&pageSize=" + Query.DEFAULT_PAGE_SIZE; } if (StringUtils.isNotEmpty(language)) { diff --git a/annotation-tests/src/integration-test/java/eu/europeana/annotation/tests/web/AnnotationSearchIT.java b/annotation-tests/src/integration-test/java/eu/europeana/annotation/tests/web/AnnotationSearchIT.java index e6f0171f0..b9f7ecfab 100644 --- a/annotation-tests/src/integration-test/java/eu/europeana/annotation/tests/web/AnnotationSearchIT.java +++ b/annotation-tests/src/integration-test/java/eu/europeana/annotation/tests/web/AnnotationSearchIT.java @@ -29,6 +29,7 @@ import eu.europeana.annotation.definitions.model.body.impl.TextBody; import eu.europeana.annotation.definitions.model.entity.impl.EdmPlace; import eu.europeana.annotation.definitions.model.graph.Graph; +import eu.europeana.annotation.definitions.model.search.Query; import eu.europeana.annotation.definitions.model.search.SearchProfiles; import eu.europeana.annotation.definitions.model.search.result.AnnotationPage; import eu.europeana.annotation.definitions.model.target.Target; @@ -108,10 +109,10 @@ public void testSearchAnnotationPaging() throws Exception { assertNotNull(annPg, "AnnotationPage must not be null"); // there might be old annotations of failing tests in the database assertTrue(TOTAL_IN_COLLECTION <= annPg.getTotalInCollection()); - assertEquals(annPg.getCurrentPage(), 0); + assertEquals(annPg.getCurrentPage(), Query.DEFAULT_PAGE); assertEquals(TOTAL_IN_PAGE, annPg.getTotalInPage()); assertEquals(TOTAL_IN_PAGE, annPg.getItems().getResultSize()); - assertNextPageNumber(annPg, 1); + assertNextPageNumber(annPg, Query.DEFAULT_PAGE+1); // second page String npUri = annPg.getNextPageUri(); @@ -128,13 +129,13 @@ public void testSearchAnnotationPaging() throws Exception { String nextCurrentPageUri = secondAnnoPg.getNextPageUri(); log.debug("nextCurrentPageUri" + nextCurrentPageUri); assertNotNull(secondAnnoPg); - assertEquals(secondAnnoPg.getCurrentPage(), 1); - assertNextPageNumber(secondAnnoPg, 2); + assertEquals(secondAnnoPg.getCurrentPage(), Query.DEFAULT_PAGE+1); + assertNextPageNumber(secondAnnoPg, Query.DEFAULT_PAGE+2); assertEquals(TOTAL_IN_PAGE, secondAnnoPg.getTotalInPage()); assertEquals(TOTAL_IN_PAGE, secondAnnoPg.getItems().getResultSize()); // last page - int lastPageNum = (int) Math.ceil((TOTAL_IN_COLLECTION - 1) / TOTAL_IN_PAGE); + int lastPageNum = ((int) Math.ceil(1.0 * TOTAL_IN_COLLECTION / TOTAL_IN_PAGE)) + Query.DEFAULT_PAGE - 1; AnnotationPage lastPage = searchAnnotationsAddQueryField(query, Integer.toString(lastPageNum), Integer.toString(TOTAL_IN_PAGE), null, null, SearchProfiles.STANDARD.toString(), null); assertEquals(lastPage.getCurrentPage(), lastPageNum); @@ -161,7 +162,7 @@ public void testSearchAnyAnnotation() throws Exception { // SearchProfiles.STANDARD); assertNotNull(annPg, "AnnotationPage must not be null"); // there might be old annotations of failing tests in the database - assertEquals(annPg.getCurrentPage(), 0); + assertEquals(annPg.getCurrentPage(), Query.DEFAULT_PAGE); List annos = annPg.getAnnotations(); @@ -1032,7 +1033,7 @@ public void testSearchDereferencedAnnotation() throws Exception { assertNotNull(annPg, "AnnotationPage must not be null"); // there must be annotations in database after initial insert in this test class assertTrue(0 <= annPg.getTotalInCollection()); - assertEquals(annPg.getCurrentPage(), 0); + assertEquals(annPg.getCurrentPage(), Query.DEFAULT_PAGE); for (Annotation foundAnnotation : annPg.getAnnotations()) { log.info(foundAnnotation.getIdentifier()); log.info(foundAnnotation.getBody().getHttpUri()); @@ -1060,7 +1061,7 @@ public void testSearchDereferencedAnnotationMultiLanguage() throws Exception { assertNotNull(annPg, "AnnotationPage must not be null"); // there must be annotations in database after initial insert in this test class assertTrue(0 <= annPg.getTotalInCollection()); - assertEquals(annPg.getCurrentPage(), 0); + assertEquals(annPg.getCurrentPage(), Query.DEFAULT_PAGE); for (Annotation foundAnnotation : annPg.getAnnotations()) { log.info(foundAnnotation.getIdentifier()); log.info(foundAnnotation.getBody().getHttpUri()); diff --git a/annotation-web/src/main/java/eu/europeana/annotation/web/service/impl/AnnotationSearchServiceImpl.java b/annotation-web/src/main/java/eu/europeana/annotation/web/service/impl/AnnotationSearchServiceImpl.java index aa0852d33..3f841dc71 100644 --- a/annotation-web/src/main/java/eu/europeana/annotation/web/service/impl/AnnotationSearchServiceImpl.java +++ b/annotation-web/src/main/java/eu/europeana/annotation/web/service/impl/AnnotationSearchServiceImpl.java @@ -100,13 +100,14 @@ public AnnotationPage search(Query query, HttpServletRequest request) throws Htt String currentPageUrl = buildPageUrl(collectionUrl, currentPage, query.getPageSize()); protocol.setCurrentPageUri(currentPageUrl); - if (currentPage > 0) { + if (currentPage > Query.DEFAULT_PAGE) { String prevPage = buildPageUrl(collectionUrl, currentPage - 1, query.getPageSize()); protocol.setPrevPageUri(prevPage); } // if current page is not the last one - boolean isLastPage = protocol.getTotalInCollection() <= (currentPage + 1) * query.getPageSize(); + final int nextPageStartIndex = (currentPage - Query.DEFAULT_PAGE + 1) * query.getPageSize(); + boolean isLastPage = protocol.getTotalInCollection() <= nextPageStartIndex; if (!isLastPage) { String nextPage = buildPageUrl(collectionUrl, currentPage + 1, query.getPageSize()); protocol.setNextPageUri(nextPage); @@ -147,18 +148,10 @@ private String buildCollectionUrl(Query query, HttpServletRequest request) { queryString += ("&" + WebAnnotationFields.PARAM_PROFILE + "=" + query.getSearchProfile().toString()); - String result = configuration.getAnnoApiEndpoint() + "/search?"; + String url = configuration.getAnnoApiEndpoint() + "/search?"; + url += queryString; - // try { - // result += URLEncoder.encode(queryString, StandardCharsets.UTF_8.toString()); - // } catch (UnsupportedEncodingException e) { - // logger.log(Level.ERROR, "The UnsupportedEncodingException during the URL encoding of the - // string.", e); - // result += queryString; - // } - result += queryString; - - return result; + return url; } protected String removeParam(final String queryParam, String queryParams) { @@ -187,7 +180,7 @@ public Query buildSearchQuery(String queryString, String[] filters, String[] fac Query searchQuery = new QueryImpl(); searchQuery.setQuery(queryString); - if (pageNr < 0) + if (pageNr < Query.DEFAULT_PAGE) searchQuery.setPageNr(Query.DEFAULT_PAGE); else searchQuery.setPageNr(pageNr);