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.jpa.ips.strategy.BaseIpsGenerationStrategy;
023import ca.uhn.fhir.rest.api.server.RequestDetails;
024import ca.uhn.fhir.rest.param.TokenParam;
025import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
026import jakarta.annotation.Nonnull;
027import jakarta.annotation.Nullable;
028import org.hl7.fhir.instance.model.api.IBaseBundle;
029import org.hl7.fhir.instance.model.api.IBaseResource;
030import org.hl7.fhir.instance.model.api.IIdType;
031
032import java.util.List;
033
034/**
035 * This interface is the primary configuration and strategy provider for the
036 * HAPI FHIR International Patient Summary (IPS) generator.
037 * <p>
038 * Note that this API will almost certainly change as more real-world experience is
039 * gained with the IPS generator.
040 */
041public interface IIpsGenerationStrategy {
042
043        /**
044         * This method returns the profile associated with the IPS document
045         * generated by this strategy.
046         */
047        String getBundleProfile();
048
049        /**
050         * This method will be called once by the framework. It can be
051         * used to perform any initialization.
052         */
053        void initialize();
054
055        /**
056         * This method should return a list of the sections to include in the
057         * generated IPS. Note that each section must have a unique value for the
058         * {@link Section#getProfile()} value.
059         */
060        @Nonnull
061        List<Section> getSections();
062
063        /**
064         * Returns the resource supplier for the given section. The resource supplier
065         * is used to supply the resources which will be used for a given
066         * section.
067         *
068         * @param theSection The section
069         */
070        @Nonnull
071        ISectionResourceSupplier getSectionResourceSupplier(@Nonnull Section theSection);
072
073        /**
074         * Provides a list of configuration property files for the IPS narrative generator.
075         * <p>
076         * Entries should be of the format <code>classpath:path/to/file.properties</code>
077         * </p>
078         * <p>
079         * If more than one file is provided, the files will be evaluated in order. Therefore you
080         * might choose to include a custom file, followed by
081         * {@link BaseIpsGenerationStrategy#DEFAULT_IPS_NARRATIVES_PROPERTIES}
082         * in order to fall back to the default templates for any sections you have not
083         * provided an explicit template for.
084         * </p>
085         */
086        List<String> getNarrativePropertyFiles();
087
088        /**
089         * Create and return a new <code>Organization</code> resource representing.
090         * the author of the IPS document. This method will be called once per IPS
091         * in order to
092         */
093        IBaseResource createAuthor();
094
095        /**
096         * Create and return a title for the composition document.
097         *
098         * @param theContext The associated context for the specific IPS document being generated.
099         */
100        String createTitle(IpsContext theContext);
101
102        /**
103         * Create and return a confidentiality code for the composition document. Must be a valid
104         * code for the element <code>Composition.confidentiality</code>
105         *
106         * @param theIpsContext The associated context for the specific IPS document being generated.
107         */
108        String createConfidentiality(IpsContext theIpsContext);
109
110        /**
111         * This method is used to determine the resource ID to assign to a resource that
112         * will be added to the IPS document Bundle. Implementations will probably either
113         * return <code>null</code> to leave the resource ID as-is, or generate a
114         * placeholder UUID to replace it with.
115         * <p>
116         * If you want to replace the native resource ID with a placeholder so as not
117         * to leak the server-generated IDs, the recommended way is to
118         * return <code>IdType.newRandomUuid()</code>
119         * </p>
120         *
121         * @param theIpsContext The associated context for the specific IPS document being
122         *                      generated. Note that this will be <code>null</code> when
123         *                      massaging the ID of the subject (Patient) resource, but will
124         *                      be populated for all subsequent calls for a given IPS
125         *                      document generation.
126         * @param theResource   The resource to massage the resource ID for
127         * @return An ID to assign to the resource, or <code>null</code> to leave the existing ID intact,
128         * meaning that the server-assigned IDs will be used in the bundle.
129         */
130        @Nullable
131        IIdType massageResourceId(@Nullable IpsContext theIpsContext, @Nonnull IBaseResource theResource);
132
133        /**
134         * Fetches and returns the patient to include in the generated IPS for the given patient ID.
135         *
136         * @throws ResourceNotFoundException If the ID is not known.
137         */
138        @Nonnull
139        IBaseResource fetchPatient(IIdType thePatientId, RequestDetails theRequestDetails) throws ResourceNotFoundException;
140
141        /**
142         * Fetches and returns the patient to include in the generated IPS for the given patient identifier.
143         *
144         * @throws ResourceNotFoundException If the ID is not known.
145         */
146        @Nonnull
147        IBaseResource fetchPatient(TokenParam thePatientIdentifier, RequestDetails theRequestDetails);
148
149        /**
150         * This method is called once for each generated IPS document, after all other processing is complete. It can
151         * be used by the strategy to make direct manipulations prior to returning the document.
152         */
153        default void postManipulateIpsBundle(IBaseBundle theBundle) {
154                // nothing
155        }
156}