001/*-
002 * #%L
003 * HAPI FHIR - Master Data Management
004 * %%
005 * Copyright (C) 2014 - 2023 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.api.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(ServletRequestDetails theServletRequestDetails, Page<MdmLinkJson> theCurrentPage, MdmPageRequest thePageRequest) {
047                String urlWithoutPaging = RestfulServerUtils.createLinkSelfWithoutGivenParameters(theServletRequestDetails.getFhirServerBase(), theServletRequestDetails, Arrays.asList(PARAM_OFFSET, PARAM_COUNT));
048                return buildMdmPageLinks(urlWithoutPaging, theCurrentPage, thePageRequest);
049        }
050
051        public static MdmPageLinkTuple buildMdmPageLinks(String theUrlWithoutPaging, Page<MdmLinkJson> theCurrentPage, MdmPageRequest thePageRequest) {
052                MdmPageLinkTuple tuple = new MdmPageLinkTuple();
053                tuple.setSelfLink(buildLinkWithOffsetAndCount(theUrlWithoutPaging, thePageRequest.getCount(), thePageRequest.getOffset()));
054                if (theCurrentPage.hasNext()) {
055                        tuple.setNextLink(buildLinkWithOffsetAndCount(theUrlWithoutPaging,thePageRequest.getCount(), thePageRequest.getNextOffset()));
056                }
057                if (theCurrentPage.hasPrevious()) {
058                        tuple.setPreviousLink(buildLinkWithOffsetAndCount(theUrlWithoutPaging,thePageRequest.getCount(), thePageRequest.getPreviousOffset()));
059                }
060                return tuple;
061
062        }
063
064        public static String buildLinkWithOffsetAndCount(String theBaseUrl, int theCount, int theOffset) {
065                StringBuilder builder = new StringBuilder();
066                builder.append(theBaseUrl);
067                if (!theBaseUrl.contains("?")) {
068                        builder.append("?");
069                } else {
070                        builder.append("&");
071                }
072                builder.append(PARAM_OFFSET).append("=").append(theOffset);
073                builder.append("&");
074                builder.append(PARAM_COUNT).append("=").append(theCount);
075                return builder.toString();
076        }
077}