001/*-
002 * #%L
003 * HAPI FHIR - Server Framework
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.rest.server.method;
021
022import ca.uhn.fhir.model.api.Include;
023import ca.uhn.fhir.model.valueset.BundleTypeEnum;
024import ca.uhn.fhir.rest.api.Constants;
025import ca.uhn.fhir.rest.api.server.IBundleProvider;
026import ca.uhn.fhir.rest.api.server.IRestfulServer;
027import ca.uhn.fhir.rest.api.server.RequestDetails;
028import ca.uhn.fhir.rest.server.RestfulServerUtils;
029import org.apache.commons.lang3.Validate;
030
031import java.util.Map;
032import java.util.Set;
033
034/**
035 * This is a request object for selecting resources from a bundle provider and returning a bundle to the client
036 */
037public class ResponseBundleRequest {
038        /**
039         * The FHIR REST server the request is coming from.  This is used to determine default page size.
040         */
041        public final IRestfulServer<?> server;
042        /**
043         * The bundle provider that will be used as the source of resources for the returned bundle.
044         */
045        public final IBundleProvider bundleProvider;
046        /**
047         * The user request details.  This is used to parse out parameters used to create the final bundle.
048         */
049        public final RequestDetails requestDetails;
050        /**
051         * The requested offset into the list of resources that should be used to create the returned bundle.
052         */
053        public final int offset;
054        /**
055         * The response bundle link to self.  This is used to create "self" link in the returned bundle.
056         */
057        public final String linkSelf;
058        /**
059         * The set of includes requested by the user.  This is used to determine which resources should be additionally
060         * included in the returned bundle.
061         */
062        public final Set<Include> includes;
063        /**
064         * The type of bundle that should be returned to the client.
065         */
066        public final BundleTypeEnum bundleType;
067        /**
068         * The id of the search used to page through search results
069         */
070        public final String searchId;
071
072        public final RequestedPage requestedPage;
073
074        public ResponseBundleRequest(
075                        IRestfulServer<?> theServer,
076                        IBundleProvider theBundleProvider,
077                        RequestDetails theRequest,
078                        int theOffset,
079                        Integer theLimit,
080                        String theLinkSelf,
081                        Set<Include> theIncludes,
082                        BundleTypeEnum theBundleType,
083                        String theSearchId) {
084                server = theServer;
085                bundleProvider = theBundleProvider;
086                requestDetails = theRequest;
087                offset = theOffset;
088                linkSelf = theLinkSelf;
089                includes = theIncludes;
090                bundleType = theBundleType;
091                searchId = theSearchId;
092                requestedPage = getRequestedPage(theLimit);
093        }
094
095        public Map<String, String[]> getRequestParameters() {
096                return requestDetails.getParameters();
097        }
098
099        private RequestedPage getRequestedPage(Integer theLimit) {
100                // If the BundleProvider has an offset and page size, we use that
101                if (bundleProvider.getCurrentPageOffset() != null) {
102                        Validate.notNull(
103                                        bundleProvider.getCurrentPageSize(),
104                                        "IBundleProvider returned a non-null offset, but did not return a non-null page size");
105                        return new RequestedPage(bundleProvider.getCurrentPageOffset(), bundleProvider.getCurrentPageSize());
106                        // Otherwise, we build it from the request
107                } else {
108                        Integer parameterOffset =
109                                        RestfulServerUtils.tryToExtractNamedParameter(requestDetails, Constants.PARAM_OFFSET);
110                        return new RequestedPage(parameterOffset, theLimit);
111                }
112        }
113}