001/* 002 * Copyright 2020 Global Biodiversity Information Facility (GBIF) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.gbif.api.util.iterables; 017 018import static org.gbif.api.util.PreconditionUtils.checkArgument; 019 020import java.util.ArrayList; 021import java.util.Iterator; 022import java.util.List; 023import java.util.Map; 024import lombok.extern.slf4j.Slf4j; 025import org.gbif.api.model.collections.descriptors.Descriptor; 026import org.gbif.api.model.collections.request.DescriptorSearchRequest; 027import org.gbif.api.model.common.paging.PagingRequest; 028import org.gbif.api.service.collections.DescriptorsService; 029 030/** Iterates over results of {@link DescriptorsService#listDescriptors(DescriptorSearchRequest)}. */ 031@Slf4j 032public class CollectionDescriptorVerbatimPager implements Iterable<Map<String, String>> { 033 034 private final DescriptorsService service; 035 private final DescriptorSearchRequest searchRequest; 036 private final int pageSize; 037 038 public CollectionDescriptorVerbatimPager( 039 DescriptorsService service, DescriptorSearchRequest searchRequest, int pageSize) { 040 checkArgument(pageSize > 0, "pageSize must be at least 1"); 041 this.pageSize = pageSize; 042 this.searchRequest = searchRequest; 043 this.service = service; 044 } 045 046 @Override 047 public Iterator<Map<String, String>> iterator() { 048 return new ResponseIterator(); 049 } 050 051 class ResponseIterator implements Iterator<Map<String, String>> { 052 private final PagingRequest page = new PagingRequest(0, pageSize); 053 private List<Map<String, String>> resp = null; 054 private Iterator<Map<String, String>> iter; 055 private Map<String, String> next; 056 057 public ResponseIterator() { 058 loadPage(); 059 next = nextEntity(); 060 } 061 062 @Override 063 public boolean hasNext() { 064 return next != null && !next.isEmpty(); 065 } 066 067 @Override 068 public Map<String, String> next() { 069 Map<String, String> entity = next; 070 next = nextEntity(); 071 return entity; 072 } 073 074 @Override 075 public void remove() { 076 throw new UnsupportedOperationException(); 077 } 078 079 private Map<String, String> nextEntity() { 080 while (true) { 081 if (!iter.hasNext()) { 082 if (resp.isEmpty()) { 083 // no more records to load, stop! 084 return null; 085 } else { 086 loadPage(); 087 } 088 } 089 if (iter.hasNext()) { 090 return iter.next(); 091 } 092 } 093 } 094 095 private void loadPage() { 096 log.debug("Loading page {}-{}", page.getOffset(), page.getOffset() + page.getLimit()); 097 resp = nextPage(page); 098 iter = resp.iterator(); 099 page.nextPage(); 100 } 101 } 102 103 public List<Map<String, String>> nextPage(PagingRequest page) { 104 searchRequest.setLimit(page.getLimit()); 105 searchRequest.setOffset(page.getOffset()); 106 107 List<Map<String, String>> result = new ArrayList<>(); 108 for (Descriptor d : service.listDescriptors(searchRequest).getResults()) { 109 result.add(d.getVerbatim()); 110 } 111 return result; 112 } 113}