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