001package ca.uhn.fhir.rest.api.server;
002
003import org.hl7.fhir.instance.model.api.IBaseResource;
004import org.hl7.fhir.instance.model.api.IPrimitiveType;
005
006import javax.annotation.Nonnull;
007import javax.annotation.Nullable;
008import java.util.Date;
009import java.util.List;
010
011/*
012 * #%L
013 * HAPI FHIR - Server Framework
014 * %%
015 * Copyright (C) 2014 - 2019 University Health Network
016 * %%
017 * Licensed under the Apache License, Version 2.0 (the "License");
018 * you may not use this file except in compliance with the License.
019 * You may obtain a copy of the License at
020 *
021 * http://www.apache.org/licenses/LICENSE-2.0
022 *
023 * Unless required by applicable law or agreed to in writing, software
024 * distributed under the License is distributed on an "AS IS" BASIS,
025 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
026 * See the License for the specific language governing permissions and
027 * limitations under the License.
028 * #L%
029 */
030
031
032public interface IBundleProvider {
033
034        /**
035         * If this method is implemented, provides an ID for the current
036         * page of results. This ID should be unique (at least within
037         * the current search as identified by {@link #getUuid()})
038         * so that it can be used to look up a specific page of results.
039         * <p>
040         * This can be used in order to allow the
041         * server paging mechanism to work using completely
042         * opaque links (links that do not encode any index/offset
043         * information), which can be useful on some servers.
044         * </p>
045         *
046         * @since 3.5.0
047         */
048        default String getCurrentPageId() {
049                return null;
050        }
051
052        /**
053         * If this method is implemented, provides an ID for the next
054         * page of results. This ID should be unique (at least within
055         * the current search as identified by {@link #getUuid()})
056         * so that it can be used to look up a specific page of results.
057         * <p>
058         * This can be used in order to allow the
059         * server paging mechanism to work using completely
060         * opaque links (links that do not encode any index/offset
061         * information), which can be useful on some servers.
062         * </p>
063         *
064         * @since 3.5.0
065         */
066        default String getNextPageId() {
067                return null;
068        }
069
070        /**
071         * If this method is implemented, provides an ID for the previous
072         * page of results. This ID should be unique (at least within
073         * the current search as identified by {@link #getUuid()})
074         * so that it can be used to look up a specific page of results.
075         * <p>
076         * This can be used in order to allow the
077         * server paging mechanism to work using completely
078         * opaque links (links that do not encode any index/offset
079         * information), which can be useful on some servers.
080         * </p>
081         *
082         * @since 3.5.0
083         */
084        default String getPreviousPageId() {
085                return null;
086        }
087
088        /**
089         * Returns the instant as of which this result was created. The
090         * result of this value is used to populate the <code>lastUpdated</code>
091         * value on search result/history result bundles.
092         */
093        IPrimitiveType<Date> getPublished();
094
095        /**
096         * Load the given collection of resources by index, plus any additional resources per the
097         * server's processing rules (e.g. _include'd resources, OperationOutcome, etc.). For example,
098         * if the method is invoked with index 0,10 the method might return 10 search results, plus an
099         * additional 20 resources which matched a client's _include specification.
100         * <p>
101         * Note that if this bundle provider was loaded using a
102         * page ID (i.e. via {@link ca.uhn.fhir.rest.server.IPagingProvider#retrieveResultList(RequestDetails, String, String)}
103         * because {@link #getNextPageId()} provided a value on the
104         * previous page, then the indexes should be ignored and the
105         * whole page returned.
106         * </p>
107         *
108         * @param theFromIndex The low index (inclusive) to return
109         * @param theToIndex   The high index (exclusive) to return
110         * @return A list of resources. The size of this list must be at least <code>theToIndex - theFromIndex</code>.
111         */
112        @Nonnull
113        List<IBaseResource> getResources(int theFromIndex, int theToIndex);
114
115        /**
116         * Returns the UUID associated with this search. Note that this
117         * does not need to return a non-null value unless it a
118         * IPagingProvider is being used that requires UUIDs
119         * being returned.
120         * <p>
121         * In other words, if you are using the default FifoMemoryPagingProvider in
122         * your server, it is fine for this method to simply return {@code null} since FifoMemoryPagingProvider
123         * does not use the value anyhow. On the other hand, if you are creating a custom
124         * IPagingProvider implementation you might use this method to communicate
125         * the search ID back to the provider.
126         * </p>
127         * <p>
128         * Note that the UUID returned by this method corresponds to
129         * the search, and not to the individual page.
130         * </p>
131         */
132        @Nullable
133        String getUuid();
134
135        /**
136         * Optionally may be used to signal a preferred page size to the server, e.g. because
137         * the implementing code recognizes that the resources which will be returned by this
138         * implementation are expensive to load so a smaller page size should be used. The value
139         * returned by this method will only be used if the client has not explicitly requested
140         * a page size.
141         *
142         * @return Returns the preferred page size or <code>null</code>
143         */
144        Integer preferredPageSize();
145
146        /**
147         * Returns the total number of results which match the given query (exclusive of any
148         * _include's or OperationOutcome). May return {@literal null} if the total size is not
149         * known or would be too expensive to calculate.
150         */
151        @Nullable
152        Integer size();
153
154        /**
155         * This method returns <code>true</code> if the bundle provider knows that at least
156         * one result exists.
157         */
158        default boolean isEmpty() {
159                Integer size = size();
160                if (size != null) {
161                        return size == 0;
162                }
163                return getResources(0, 1).isEmpty();
164        }
165
166}