001/*- 002 * #%L 003 * HAPI FHIR - Master Data Management 004 * %% 005 * Copyright (C) 2014 - 2024 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.mdm.api.paging; 021 022import ca.uhn.fhir.i18n.Msg; 023import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; 024import jakarta.annotation.Nullable; 025import org.apache.commons.lang3.StringUtils; 026import org.hl7.fhir.instance.model.api.IPrimitiveType; 027import org.springframework.data.domain.PageRequest; 028 029import static ca.uhn.fhir.rest.api.Constants.PARAM_COUNT; 030import static ca.uhn.fhir.rest.api.Constants.PARAM_OFFSET; 031 032/** 033 * This class is essentially just a data clump of offset + count, as well as the ability to convert itself into a standard 034 * {@link PageRequest} for spring data to use. The reason we don't use PageRequest natively is because it is concerned with `pages` and `counts`, 035 * but we are using `offset` and `count` which requires some minor translation. 036 */ 037public class MdmPageRequest { 038 039 private final int myPage; 040 private final int myOffset; 041 private final int myCount; 042 043 public MdmPageRequest( 044 @Nullable IPrimitiveType<Integer> theOffset, 045 @Nullable IPrimitiveType<Integer> theCount, 046 int theDefaultPageSize, 047 int theMaximumPageSize) { 048 myOffset = theOffset == null ? 0 : theOffset.getValue(); 049 myCount = theCount == null ? theDefaultPageSize : Math.min(theCount.getValue(), theMaximumPageSize); 050 validatePagingParameters(myOffset, myCount); 051 052 this.myPage = myOffset / myCount; 053 } 054 055 public MdmPageRequest( 056 @Nullable Integer theOffset, @Nullable Integer theCount, int theDefaultPageSize, int theMaximumPageSize) { 057 myOffset = theOffset == null ? 0 : theOffset; 058 myCount = theCount == null ? theDefaultPageSize : Math.min(theCount, theMaximumPageSize); 059 validatePagingParameters(myOffset, myCount); 060 061 this.myPage = myOffset / myCount; 062 } 063 064 private void validatePagingParameters(int theOffset, int theCount) { 065 String errorMessage = ""; 066 067 if (theOffset < 0) { 068 errorMessage += PARAM_OFFSET + " must be greater than or equal to 0. "; 069 } 070 if (theCount <= 0) { 071 errorMessage += PARAM_COUNT + " must be greater than 0."; 072 } 073 if (StringUtils.isNotEmpty(errorMessage)) { 074 throw new InvalidRequestException(Msg.code(1524) + errorMessage); 075 } 076 } 077 078 public int getOffset() { 079 return myOffset; 080 } 081 082 public int getPage() { 083 return myPage; 084 } 085 086 public int getCount() { 087 return myCount; 088 } 089 090 public int getNextOffset() { 091 return myOffset + myCount; 092 } 093 094 public int getPreviousOffset() { 095 return myOffset - myCount; 096 } 097 098 public PageRequest toPageRequest() { 099 return PageRequest.of(this.myPage, this.myCount); 100 } 101}