001/*-
002 * #%L
003 * HAPI FHIR JPA Server - International Patient Summary (IPS)
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.jpa.ips.api;
021
022import ca.uhn.fhir.rest.api.server.RequestDetails;
023import jakarta.annotation.Nonnull;
024import jakarta.annotation.Nullable;
025import org.hl7.fhir.instance.model.api.IBaseResource;
026import org.thymeleaf.util.Validate;
027
028import java.util.List;
029
030/**
031 * This interface is invoked for each section of the IPS, and fetches/returns the
032 * resources which will be included in the IPS document for that section. This
033 * might be by performing a search in a local repository, but could also be
034 * done by calling a remote repository, performing a calculation, making
035 * JDBC database calls directly, etc.
036 * <p>
037 * Note that you only need to implement this interface directly if you want to
038 * provide manual logic for gathering and preparing resources to include in
039 * an IPS document. If your resources can be collected by querying a JPS
040 * repository, you can use {@link ca.uhn.fhir.jpa.ips.jpa.JpaSectionResourceSupplier}
041 * as the implementation of this interface, and
042 * {@link ca.uhn.fhir.jpa.ips.jpa.IJpaSectionSearchStrategy} becomes the class
043 * that is used to define your searches.
044 * </p>
045 *
046 * @since 7.2.0
047 * @see ca.uhn.fhir.jpa.ips.jpa.JpaSectionResourceSupplier
048 */
049public interface ISectionResourceSupplier {
050
051        /**
052         * This method will be called once for each section context (section and resource type combination),
053         * and will be used to supply the resources to include in the given IPS section. This method can
054         * be used if you wish to fetch resources for a given section from a source other than
055         * the repository. This could mean fetching resources using a FHIR REST client to an
056         * external server, or could even mean fetching data directly from a database using JDBC
057         * or similar.
058         *
059         * @param theIpsContext     The IPS context, containing the identity of the patient whose IPS is being generated.
060         * @param theSectionContext The section context, containing the section name and resource type.
061         * @param theRequestDetails The RequestDetails object associated with the HTTP request associated with this generation.
062         * @return Returns a list of resources to add to the given section, or <code>null</code>.
063         */
064        @Nullable
065        <T extends IBaseResource> List<ResourceEntry> fetchResourcesForSection(
066                        IpsContext theIpsContext, IpsSectionContext<T> theSectionContext, RequestDetails theRequestDetails);
067
068        /**
069         * This enum specifies how an individual {@link ResourceEntry resource entry} that
070         * is returned by {@link #fetchResourcesForSection(IpsContext, IpsSectionContext, RequestDetails)}
071         * should be included in the resulting IPS document bundle.
072         */
073        enum InclusionTypeEnum {
074
075                /**
076                 * The resource should be included in the document bundle and linked to
077                 * from the Composition via the <code>Composition.section.entry</code>
078                 * reference.
079                 */
080                PRIMARY_RESOURCE,
081
082                /**
083                 * The resource should be included in the document bundle, but not directly
084                 * linked from the composition. This typically means that it is referenced
085                 * by at least one primary resource.
086                 */
087                SECONDARY_RESOURCE,
088
089                /**
090                 * Do not include this resource in the document
091                 */
092                EXCLUDE
093        }
094
095        /**
096         * This class is the return type for {@link #fetchResourcesForSection(IpsContext, IpsSectionContext, RequestDetails)}.
097         */
098        class ResourceEntry {
099
100                private final IBaseResource myResource;
101
102                private final InclusionTypeEnum myInclusionType;
103
104                /**
105                 * Constructor
106                 *
107                 * @param theResource The resource to include (must not be null)
108                 * @param theInclusionType The inclusion type (must not be null)
109                 */
110                public ResourceEntry(@Nonnull IBaseResource theResource, @Nonnull InclusionTypeEnum theInclusionType) {
111                        Validate.notNull(theResource, "theResource must not be null");
112                        Validate.notNull(theInclusionType, "theInclusionType must not be null");
113                        myResource = theResource;
114                        myInclusionType = theInclusionType;
115                }
116
117                public IBaseResource getResource() {
118                        return myResource;
119                }
120
121                public InclusionTypeEnum getInclusionType() {
122                        return myInclusionType;
123                }
124        }
125}