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.mdm.model.mdmevents.MdmLinkJson;
023import ca.uhn.fhir.rest.server.RestfulServerUtils;
024import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
025import org.springframework.data.domain.Page;
026
027import java.util.Arrays;
028
029import static ca.uhn.fhir.rest.api.Constants.PARAM_COUNT;
030import static ca.uhn.fhir.rest.api.Constants.PARAM_OFFSET;
031
032/**
033 * Builder to generate {@link MdmPageLinkTuple} objects, based on a given page of data and the incoming page request.
034 */
035public final class MdmPageLinkBuilder {
036
037        /**
038         * Generates an {@link MdmPageLinkTuple} which contains previous/self/next links for pagination purposes.
039         *
040         * @param theServletRequestDetails the incoming request details. Used to determine server base.
041         * @param theCurrentPage the page of MDM link data. Used for determining if there are next/previous pages available.
042         * @param thePageRequest the incoming Page request, containing requested offset and count. Used for building offset for outgoing URLs.
043         *
044         * @return the {@link MdmPageLinkTuple}
045         */
046        public static MdmPageLinkTuple buildMdmPageLinks(
047                        ServletRequestDetails theServletRequestDetails,
048                        Page<MdmLinkJson> theCurrentPage,
049                        MdmPageRequest thePageRequest) {
050                String urlWithoutPaging = RestfulServerUtils.createLinkSelfWithoutGivenParameters(
051                                theServletRequestDetails.getFhirServerBase(),
052                                theServletRequestDetails,
053                                Arrays.asList(PARAM_OFFSET, PARAM_COUNT));
054                return buildMdmPageLinks(urlWithoutPaging, theCurrentPage, thePageRequest);
055        }
056
057        public static MdmPageLinkTuple buildMdmPageLinks(
058                        String theUrlWithoutPaging, Page<MdmLinkJson> theCurrentPage, MdmPageRequest thePageRequest) {
059                MdmPageLinkTuple tuple = new MdmPageLinkTuple();
060                tuple.setSelfLink(buildLinkWithOffsetAndCount(
061                                theUrlWithoutPaging, thePageRequest.getCount(), thePageRequest.getOffset()));
062                if (theCurrentPage.hasNext()) {
063                        tuple.setNextLink(buildLinkWithOffsetAndCount(
064                                        theUrlWithoutPaging, thePageRequest.getCount(), thePageRequest.getNextOffset()));
065                }
066                if (theCurrentPage.hasPrevious()) {
067                        tuple.setPreviousLink(buildLinkWithOffsetAndCount(
068                                        theUrlWithoutPaging, thePageRequest.getCount(), thePageRequest.getPreviousOffset()));
069                }
070                return tuple;
071        }
072
073        public static String buildLinkWithOffsetAndCount(String theBaseUrl, int theCount, int theOffset) {
074                StringBuilder builder = new StringBuilder();
075                builder.append(theBaseUrl);
076                if (!theBaseUrl.contains("?")) {
077                        builder.append("?");
078                } else {
079                        builder.append("&");
080                }
081                builder.append(PARAM_OFFSET).append("=").append(theOffset);
082                builder.append("&");
083                builder.append(PARAM_COUNT).append("=").append(theCount);
084                return builder.toString();
085        }
086}