001/* 002 * Licensed under the Apache License, Version 2.0 (the "License"); 003 * you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at 005 * 006 * http://www.apache.org/licenses/LICENSE-2.0 007 * 008 * Unless required by applicable law or agreed to in writing, software 009 * distributed under the License is distributed on an "AS IS" BASIS, 010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 011 * See the License for the specific language governing permissions and 012 * limitations under the License. 013 */ 014package org.gbif.api.util.iterables; 015 016import org.gbif.api.model.collections.Institution; 017import org.gbif.api.model.collections.request.CollectionSearchRequest; 018import org.gbif.api.model.collections.request.InstitutionSearchRequest; 019import org.gbif.api.model.collections.view.CollectionView; 020import org.gbif.api.model.common.paging.Pageable; 021import org.gbif.api.model.common.paging.PagingConstants; 022import org.gbif.api.model.common.paging.PagingRequest; 023import org.gbif.api.model.common.paging.PagingResponse; 024import org.gbif.api.model.occurrence.DownloadStatistics; 025import org.gbif.api.model.registry.Dataset; 026import org.gbif.api.model.registry.DatasetOccurrenceDownloadUsage; 027import org.gbif.api.model.registry.Node; 028import org.gbif.api.model.registry.Organization; 029import org.gbif.api.model.registry.search.DatasetSearchRequest; 030import org.gbif.api.model.registry.search.DatasetSearchResult; 031import org.gbif.api.service.collections.CollectionService; 032import org.gbif.api.service.collections.InstitutionService; 033import org.gbif.api.service.registry.DatasetSearchService; 034import org.gbif.api.service.registry.DatasetService; 035import org.gbif.api.service.registry.InstallationService; 036import org.gbif.api.service.registry.NetworkService; 037import org.gbif.api.service.registry.NodeService; 038import org.gbif.api.service.registry.OccurrenceDownloadService; 039import org.gbif.api.service.registry.OrganizationService; 040import org.gbif.api.vocabulary.Country; 041import org.gbif.api.vocabulary.DatasetType; 042 043import java.util.Collections; 044import java.util.Date; 045import java.util.Optional; 046import java.util.UUID; 047import java.util.function.Function; 048 049import javax.annotation.Nullable; 050 051import org.slf4j.Logger; 052import org.slf4j.LoggerFactory; 053 054/** 055 * Factory constructing registry entity iterables using specific pagers under the hood. 056 */ 057@SuppressWarnings("unused") 058public class Iterables { 059 private static final Logger LOG = LoggerFactory.getLogger(Iterables.class); 060 061 /** 062 * Private default constructor. 063 */ 064 private Iterables() { 065 //empty private constructor 066 } 067 068 /** 069 * @param key a valid dataset, organization or installation key. If null all datasets will be iterated over 070 * @throws IllegalArgumentException if given key is not existing 071 */ 072 public static Iterable<Dataset> datasets(@Nullable UUID key, @Nullable DatasetType type, 073 DatasetService ds, OrganizationService os, InstallationService is, 074 NetworkService ns, NodeService nos) { 075 return datasets(key, type, ds, os, is, ns, nos, PagingConstants.DEFAULT_PARAM_LIMIT); 076 } 077 078 /** 079 * Returns a dataset iterable by testing the given registry key first to see whether it is a dataset, organization or installation. 080 * In case of an organization key the published datasets will be returned. 081 * 082 * @param key a valid dataset, organization or installation key. If null all datasets will be iterated over 083 * @param pageSize to use when talking to the registry 084 * @throws IllegalArgumentException if given key is not existing 085 */ 086 public static Iterable<Dataset> datasets(@Nullable UUID key, @Nullable DatasetType type, 087 DatasetService ds, OrganizationService os, InstallationService is, 088 NetworkService ns, NodeService nos, int pageSize) { 089 if (key == null) { 090 LOG.info("Iterate over all {} datasets", type == null ? "" : type); 091 return new DatasetPager(ds, type, pageSize); 092 093 } else if (isDataset(key, ds)) { 094 LOG.info("Iterate over dataset {}", key); 095 return Collections.singletonList(ds.get(key)); 096 097 } else if (isOrganization(key, os)) { 098 LOG.info("Iterate over all {} datasets published by {}", type == null ? "" : type, key); 099 return new OrgPublishingPager(os, key, type, pageSize); 100 101 } else if (isInstallation(key, is)) { 102 LOG.info("Iterate over all {} datasets hosted by installation {}", type == null ? "" : type, key); 103 return new InstallationPager(is, key, type, pageSize); 104 105 } else if (isNode(key, nos)) { 106 LOG.info("Iterate over all {} datasets endorsed by node {}", type == null ? "" : type, key); 107 return new NetworkPager(ns, key, type, pageSize); 108 109 } else if (isNetwork(key, ns)) { 110 LOG.info("Iterate over all {} datasets belonging to network {}", type == null ? "" : type, key); 111 return new NodeDatasetPager(nos, key, type, pageSize); 112 } 113 throw new IllegalArgumentException("Given key is no valid GBIF registry key: " + key); 114 } 115 116 /** 117 * @param type an optional filter to just include the given dataset type 118 */ 119 public static Iterable<Dataset> datasets(@Nullable DatasetType type, DatasetService service) { 120 LOG.info("Iterate over all {} datasets", type == null ? "" : type); 121 return new DatasetPager(service, type, PagingConstants.DEFAULT_PARAM_LIMIT); 122 } 123 124 /** 125 * Iterates over dataset search results. 126 */ 127 public static Iterable<DatasetSearchResult> datasetSearchResults(@Nullable DatasetSearchRequest datasetSearchRequest, 128 DatasetSearchService datasetSearchService, 129 @Nullable Integer limit) { 130 return new DatasetSearchResultsPager(datasetSearchService, datasetSearchRequest, 131 Optional.ofNullable(limit).orElse(PagingConstants.DEFAULT_PARAM_LIMIT)); 132 } 133 134 /** 135 * @param key a valid organization key 136 * @param type an optional filter to just include the given dataset type 137 */ 138 public static Iterable<Dataset> publishedDatasets(UUID key, @Nullable DatasetType type, OrganizationService service) { 139 LOG.info("Iterate over all {} datasets published by {}", type == null ? "" : type, key); 140 return new OrgPublishingPager(service, key, type, PagingConstants.DEFAULT_PARAM_LIMIT); 141 } 142 143 /** 144 * @param key a valid organization key 145 * @param type an optional filter to just include the given dataset type 146 */ 147 public static Iterable<Dataset> hostedDatasets(UUID key, @Nullable DatasetType type, OrganizationService service) { 148 LOG.info("Iterate over all {} datasets hosted by organization {}", type == null ? "" : type, key); 149 return new OrgHostingPager(service, key, type, PagingConstants.DEFAULT_PARAM_LIMIT); 150 } 151 152 /** 153 * @param key a valid installation key 154 * @param type an optional filter to just include the given dataset type 155 */ 156 public static Iterable<Dataset> hostedDatasets(UUID key, @Nullable DatasetType type, InstallationService service) { 157 LOG.info("Iterate over all {} datasets hosted by installation {}", type == null ? "" : type, key); 158 return new InstallationPager(service, key, type, PagingConstants.DEFAULT_PARAM_LIMIT); 159 } 160 161 /** 162 * @param key a valid dataset key 163 */ 164 public static Iterable<Dataset> constituentDatasets(UUID key, DatasetService service) { 165 LOG.info("Iterate over all constituent datasets of {}", key); 166 return new DatasetConstituentPager(service, key, PagingConstants.DEFAULT_PARAM_LIMIT); 167 } 168 169 /** 170 * Iterates over all constituents of a given network. 171 * @param key a valid network key 172 * @param type an optional filter to just include the given dataset type 173 */ 174 public static Iterable<Dataset> networkDatasets(UUID key, @Nullable DatasetType type, NetworkService service) { 175 LOG.info("Iterate over all {} datasets belonging to network {}", type == null ? "" : type, key); 176 return new NetworkPager(service, key, type, PagingConstants.DEFAULT_PARAM_LIMIT); 177 } 178 179 /** 180 * @param nodeKey a valid endorsing node key 181 * @param type an optional filter to just include the given dataset type 182 */ 183 public static Iterable<Dataset> endorsedDatasets(UUID nodeKey, @Nullable DatasetType type, NodeService service) { 184 LOG.info("Iterate over all {} datasets endorsed by node {}", type == null ? "" : type, nodeKey); 185 return new NodeDatasetPager(service, nodeKey, type, PagingConstants.DEFAULT_PARAM_LIMIT); 186 } 187 188 /** 189 * 190 * @param pager producer function of next page response 191 * @return a dataset iterable based on producer function 192 */ 193 public static Iterable<Dataset> datasetsIterable(Function<PagingRequest, PagingResponse<Dataset>> pager) { 194 return new DatasetBasePager(null, PagingConstants.DEFAULT_PARAM_LIMIT) { 195 @Override 196 public PagingResponse<Dataset> nextPage(PagingRequest page) { 197 return pager.apply(page); 198 } 199 }; 200 } 201 202 /** 203 * @param country an optional country filter 204 */ 205 public static Iterable<Organization> organizations(@Nullable Country country, OrganizationService service) { 206 LOG.info("Iterate over all organizations {}", country == null ? "" : "from country "+country); 207 return new OrganizationPager(service, country, PagingConstants.DEFAULT_PARAM_LIMIT); 208 } 209 210 /** 211 * @param nodeKey a valid endorsing node key 212 */ 213 public static Iterable<Organization> endorsedOrganizations(UUID nodeKey, NodeService service) { 214 LOG.info("Iterate over all organizations endorsed by node {}", nodeKey); 215 return new NodeOrganizationPager(service, nodeKey, PagingConstants.DEFAULT_PARAM_LIMIT); 216 } 217 218 /** 219 * Iterate over all endorsing nodes 220 */ 221 public static Iterable<Node> nodes(NodeService service) { 222 LOG.info("Iterate over all nodes"); 223 return new NodePager(service, PagingConstants.DEFAULT_PARAM_LIMIT); 224 } 225 226 /** 227 * Iterable for {@link OccurrenceDownloadService#getDownloadStatistics(Date, Date, Country, UUID, UUID, Pageable)}. 228 */ 229 public static Iterable<DownloadStatistics> downloadStatistics(OccurrenceDownloadService service, 230 @Nullable Date fromDate, 231 @Nullable Date toDate, 232 @Nullable Country publishingCountry, 233 @Nullable UUID datasetKey, 234 @Nullable UUID publishingOrgKey, 235 @Nullable Integer limit) { 236 LOG.info("Iterate over download statistics"); 237 return new DownloadStatisticPager(service, fromDate, toDate, 238 publishingCountry, datasetKey, publishingOrgKey, 239 Optional.ofNullable(limit).orElse(PagingConstants.DEFAULT_PARAM_LIMIT)); 240 } 241 242 /** 243 * Iterable for {@link OccurrenceDownloadService#listDatasetUsages(String, Pageable)}. 244 */ 245 public static Iterable<DatasetOccurrenceDownloadUsage> datasetOccurrenceDownloadUsages(OccurrenceDownloadService service, 246 String downloadKey, 247 @Nullable Integer limit) { 248 LOG.info("Iterate over download dataset usages of download {}", downloadKey); 249 return new DatasetOccurrenceDownloadUsagesPager(service, 250 downloadKey, 251 Optional.ofNullable(limit).orElse(PagingConstants.DEFAULT_PARAM_LIMIT)); 252 } 253 254 /** 255 * Iterable for {@link CollectionService#list(CollectionSearchRequest)}. 256 */ 257 public static Iterable<CollectionView> collections(CollectionSearchRequest searchRequest, 258 CollectionService service, 259 @Nullable Integer limit) { 260 LOG.info("Iterating over a collection's search results"); 261 return new CollectionsPager(service, searchRequest, Optional.ofNullable(limit).orElse(PagingConstants.DEFAULT_PARAM_LIMIT)); 262 } 263 264 /** 265 * Iterable for {@link InstitutionService#list(InstitutionSearchRequest)}. 266 */ 267 public static Iterable<Institution> institutions(InstitutionSearchRequest searchRequest, 268 InstitutionService service, 269 @Nullable Integer limit) { 270 LOG.info("Iterating over a institution's search results"); 271 return new InstitutionsPager(service, searchRequest, Optional.ofNullable(limit).orElse(PagingConstants.DEFAULT_PARAM_LIMIT)); 272 } 273 274 private static boolean isDataset(UUID key, DatasetService ds) { 275 return ds.get(key) != null; 276 } 277 278 private static boolean isOrganization(UUID key, OrganizationService os) { 279 return os.get(key) != null; 280 } 281 282 private static boolean isInstallation(UUID key, InstallationService is) { 283 return is.get(key) != null; 284 } 285 286 private static boolean isNetwork(UUID key, NetworkService ns) { 287 return ns.get(key) != null; 288 } 289 290 private static boolean isNode(UUID key, NodeService ns) { 291 return ns.get(key) != null; 292 } 293}