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.ws.server.provider; 015 016import org.gbif.api.model.common.paging.Pageable; 017import org.gbif.api.model.common.paging.PagingRequest; 018 019import java.util.Map; 020 021import org.slf4j.Logger; 022import org.slf4j.LoggerFactory; 023import org.springframework.web.context.request.WebRequest; 024 025import static org.gbif.api.model.common.paging.PagingConstants.DEFAULT_PARAM_LIMIT; 026import static org.gbif.api.model.common.paging.PagingConstants.DEFAULT_PARAM_OFFSET; 027import static org.gbif.api.model.common.paging.PagingConstants.PARAM_LIMIT; 028import static org.gbif.api.model.common.paging.PagingConstants.PARAM_OFFSET; 029import static org.gbif.ws.util.CommonWsUtils.getFirst; 030 031/** 032 * Provider class that extracts the page size and offset from the query parameters, or provides the default 033 * implementation if necessary. 034 * <p/> 035 * Example resource use: 036 * <pre> 037 * {@code 038 * public List<Checklist> list(Pageable pageable) { 039 * // do stuff 040 * } 041 * } 042 * </pre> 043 * <p/> 044 */ 045public class PageableProvider implements ContextProvider<Pageable> { 046 047 private static final Logger LOG = LoggerFactory.getLogger(PageableProvider.class); 048 049 private final Integer maxPageSize; 050 051 private static final int LIMIT_CAP = 1000; 052 053 public PageableProvider() { 054 this.maxPageSize = LIMIT_CAP; 055 } 056 057 public PageableProvider(Integer maxPageSize) { 058 this.maxPageSize = maxPageSize; 059 } 060 061 @Override 062 public Pageable getValue(WebRequest webRequest) { 063 return getPagingRequest(webRequest, maxPageSize); 064 } 065 066 public static PagingRequest getPagingRequest(WebRequest webRequest, int maxPageSize) { 067 Map<String, String[]> params = webRequest.getParameterMap(); 068 069 int limit = DEFAULT_PARAM_LIMIT; 070 String limitParam = getFirst(params, PARAM_LIMIT); 071 if (limitParam != null) { 072 try { 073 limit = Integer.parseInt(limitParam); 074 if (limit < 0) { 075 LOG.info( 076 "Limit parameter was no positive integer [{}]. Using default {}", 077 limitParam, 078 DEFAULT_PARAM_LIMIT); 079 limit = DEFAULT_PARAM_LIMIT; 080 } else if (limit > maxPageSize) { 081 LOG.debug("Limit parameter too high. Use maximum {}", maxPageSize); 082 limit = maxPageSize; 083 } 084 } catch (NumberFormatException e) { 085 LOG.warn( 086 "Unparsable value supplied for limit [{}]. Using default {}", 087 limitParam, 088 DEFAULT_PARAM_LIMIT); 089 } 090 } 091 092 long offset = DEFAULT_PARAM_OFFSET; 093 String offsetParam = getFirst(params, PARAM_OFFSET); 094 if (offsetParam != null) { 095 try { 096 offset = Long.parseLong(offsetParam); 097 if (offset < 0) { 098 LOG.warn( 099 "Offset parameter is a negative integer [{}]. Using default {}", 100 offsetParam, 101 DEFAULT_PARAM_OFFSET); 102 offset = DEFAULT_PARAM_OFFSET; 103 } 104 } catch (NumberFormatException e) { 105 LOG.warn( 106 "Unparsable value supplied for offset [{}]. Using default {}", 107 offsetParam, 108 DEFAULT_PARAM_OFFSET); 109 } 110 } 111 return new PagingRequest(offset, limit); 112 } 113}