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.jpa;
021
022import ca.uhn.fhir.context.FhirContext;
023import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
024import ca.uhn.fhir.jpa.ips.api.Section;
025import ca.uhn.fhir.jpa.ips.jpa.section.AdvanceDirectivesJpaSectionSearchStrategy;
026import ca.uhn.fhir.jpa.ips.jpa.section.AllergyIntoleranceJpaSectionSearchStrategy;
027import ca.uhn.fhir.jpa.ips.jpa.section.DiagnosticResultsJpaSectionSearchStrategyDiagnosticReport;
028import ca.uhn.fhir.jpa.ips.jpa.section.DiagnosticResultsJpaSectionSearchStrategyObservation;
029import ca.uhn.fhir.jpa.ips.jpa.section.FunctionalStatusJpaSectionSearchStrategy;
030import ca.uhn.fhir.jpa.ips.jpa.section.IllnessHistoryJpaSectionSearchStrategy;
031import ca.uhn.fhir.jpa.ips.jpa.section.ImmunizationsJpaSectionSearchStrategy;
032import ca.uhn.fhir.jpa.ips.jpa.section.MedicalDevicesJpaSectionSearchStrategy;
033import ca.uhn.fhir.jpa.ips.jpa.section.MedicationSummaryJpaSectionSearchStrategyMedicationAdministration;
034import ca.uhn.fhir.jpa.ips.jpa.section.MedicationSummaryJpaSectionSearchStrategyMedicationDispense;
035import ca.uhn.fhir.jpa.ips.jpa.section.MedicationSummaryJpaSectionSearchStrategyMedicationRequest;
036import ca.uhn.fhir.jpa.ips.jpa.section.MedicationSummaryJpaSectionSearchStrategyMedicationStatement;
037import ca.uhn.fhir.jpa.ips.jpa.section.PlanOfCareJpaSectionSearchStrategy;
038import ca.uhn.fhir.jpa.ips.jpa.section.PregnancyJpaSectionSearchStrategy;
039import ca.uhn.fhir.jpa.ips.jpa.section.ProblemListJpaSectionSearchStrategy;
040import ca.uhn.fhir.jpa.ips.jpa.section.ProceduresJpaSectionSearchStrategy;
041import ca.uhn.fhir.jpa.ips.jpa.section.SocialHistoryJpaSectionSearchStrategy;
042import ca.uhn.fhir.jpa.ips.jpa.section.VitalSignsJpaSectionSearchStrategy;
043import ca.uhn.fhir.jpa.ips.strategy.AllergyIntoleranceNoInfoR4Generator;
044import ca.uhn.fhir.jpa.ips.strategy.BaseIpsGenerationStrategy;
045import ca.uhn.fhir.jpa.ips.strategy.MedicationNoInfoR4Generator;
046import ca.uhn.fhir.jpa.ips.strategy.ProblemNoInfoR4Generator;
047import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
048import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
049import ca.uhn.fhir.rest.api.server.IBundleProvider;
050import ca.uhn.fhir.rest.api.server.RequestDetails;
051import ca.uhn.fhir.rest.param.TokenParam;
052import ca.uhn.fhir.util.ValidateUtil;
053import jakarta.annotation.Nonnull;
054import org.hl7.fhir.instance.model.api.IBaseResource;
055import org.hl7.fhir.instance.model.api.IIdType;
056import org.hl7.fhir.r4.model.AllergyIntolerance;
057import org.hl7.fhir.r4.model.CarePlan;
058import org.hl7.fhir.r4.model.ClinicalImpression;
059import org.hl7.fhir.r4.model.Condition;
060import org.hl7.fhir.r4.model.Consent;
061import org.hl7.fhir.r4.model.DeviceUseStatement;
062import org.hl7.fhir.r4.model.DiagnosticReport;
063import org.hl7.fhir.r4.model.Immunization;
064import org.hl7.fhir.r4.model.MedicationAdministration;
065import org.hl7.fhir.r4.model.MedicationDispense;
066import org.hl7.fhir.r4.model.MedicationRequest;
067import org.hl7.fhir.r4.model.MedicationStatement;
068import org.hl7.fhir.r4.model.Observation;
069import org.hl7.fhir.r4.model.Patient;
070import org.hl7.fhir.r4.model.Procedure;
071import org.springframework.beans.factory.annotation.Autowired;
072import org.thymeleaf.util.Validate;
073
074import java.util.ArrayList;
075import java.util.HashSet;
076import java.util.List;
077import java.util.function.Function;
078
079/**
080 * This {@link ca.uhn.fhir.jpa.ips.api.IIpsGenerationStrategy generation strategy} contains default rules for fetching
081 * IPS section contents for each of the base (universal realm) IPS definition sections. It fetches contents for each
082 * section from the JPA server repository.
083 * <p>
084 * This class can be used directly, but it can also be subclassed and extended if you want to
085 * create an IPS strategy that is based on the defaults but add or change the inclusion rules or
086 * sections. If you are subclassing this class, the typical approach is to override the
087 * {@link #addSections()} method and replace it with your own implementation. You can include
088 * any of the same sections that are defined in the parent class, but you can also omit any
089 * you don't want to include, and add your own as well.
090 * </p>
091 */
092public class DefaultJpaIpsGenerationStrategy extends BaseIpsGenerationStrategy {
093
094        public static final String SECTION_CODE_ALLERGY_INTOLERANCE = "48765-2";
095        public static final String SECTION_CODE_MEDICATION_SUMMARY = "10160-0";
096        public static final String SECTION_CODE_PROBLEM_LIST = "11450-4";
097        public static final String SECTION_CODE_IMMUNIZATIONS = "11369-6";
098        public static final String SECTION_CODE_PROCEDURES = "47519-4";
099        public static final String SECTION_CODE_MEDICAL_DEVICES = "46264-8";
100        public static final String SECTION_CODE_DIAGNOSTIC_RESULTS = "30954-2";
101        public static final String SECTION_CODE_VITAL_SIGNS = "8716-3";
102        public static final String SECTION_CODE_PREGNANCY = "10162-6";
103        public static final String SECTION_CODE_SOCIAL_HISTORY = "29762-2";
104        public static final String SECTION_CODE_ILLNESS_HISTORY = "11348-0";
105        public static final String SECTION_CODE_FUNCTIONAL_STATUS = "47420-5";
106        public static final String SECTION_CODE_PLAN_OF_CARE = "18776-5";
107        public static final String SECTION_CODE_ADVANCE_DIRECTIVES = "42348-3";
108        public static final String SECTION_SYSTEM_LOINC = ITermLoaderSvc.LOINC_URI;
109        private final List<Function<Section, Section>> myGlobalSectionCustomizers = new ArrayList<>();
110
111        @Autowired
112        private DaoRegistry myDaoRegistry;
113
114        @Autowired
115        private FhirContext myFhirContext;
116
117        private boolean myInitialized;
118
119        public void setDaoRegistry(DaoRegistry theDaoRegistry) {
120                myDaoRegistry = theDaoRegistry;
121        }
122
123        public void setFhirContext(FhirContext theFhirContext) {
124                myFhirContext = theFhirContext;
125        }
126
127        /**
128         * Subclasses may call this method to add customers that will customize every section
129         * added to the strategy.
130         */
131        public void addGlobalSectionCustomizer(@Nonnull Function<Section, Section> theCustomizer) {
132                Validate.isTrue(!myInitialized, "This method must not be called after the strategy is initialized");
133                Validate.notNull(theCustomizer, "theCustomizer must not be null");
134                myGlobalSectionCustomizers.add(theCustomizer);
135        }
136
137        @Override
138        public final void initialize() {
139                Validate.isTrue(!myInitialized, "Strategy must not be initialized twice");
140                Validate.isTrue(myDaoRegistry != null, "No DaoRegistry has been supplied");
141                Validate.isTrue(myFhirContext != null, "No FhirContext has been supplied");
142                addSections();
143                myInitialized = true;
144        }
145
146        @Nonnull
147        @Override
148        public IBaseResource fetchPatient(IIdType thePatientId, RequestDetails theRequestDetails) {
149                return myDaoRegistry.getResourceDao("Patient").read(thePatientId, theRequestDetails);
150        }
151
152        @Nonnull
153        @Override
154        public IBaseResource fetchPatient(TokenParam thePatientIdentifier, RequestDetails theRequestDetails) {
155                SearchParameterMap searchParameterMap =
156                                new SearchParameterMap().setLoadSynchronousUpTo(2).add(Patient.SP_IDENTIFIER, thePatientIdentifier);
157                IBundleProvider searchResults =
158                                myDaoRegistry.getResourceDao("Patient").search(searchParameterMap, theRequestDetails);
159
160                ValidateUtil.isTrueOrThrowResourceNotFound(
161                                searchResults.sizeOrThrowNpe() > 0, "No Patient could be found matching given identifier");
162                ValidateUtil.isTrueOrThrowInvalidRequest(
163                                searchResults.sizeOrThrowNpe() == 1, "Multiple Patient resources were found matching given identifier");
164
165                return searchResults.getResources(0, 1).get(0);
166        }
167
168        /**
169         * Add the various sections to the registry in order. This method can be overridden for
170         * customization.
171         */
172        protected void addSections() {
173                addJpaSectionAllergyIntolerance();
174                addJpaSectionMedicationSummary();
175                addJpaSectionProblemList();
176                addJpaSectionImmunizations();
177                addJpaSectionProcedures();
178                addJpaSectionMedicalDevices();
179                addJpaSectionDiagnosticResults();
180                addJpaSectionVitalSigns();
181                addJpaSectionPregnancy();
182                addJpaSectionSocialHistory();
183                addJpaSectionIllnessHistory();
184                addJpaSectionFunctionalStatus();
185                addJpaSectionPlanOfCare();
186                addJpaSectionAdvanceDirectives();
187        }
188
189        protected void addJpaSectionAllergyIntolerance() {
190                Section section = Section.newBuilder()
191                                .withTitle("Allergies and Intolerances")
192                                .withSectionSystem(SECTION_SYSTEM_LOINC)
193                                .withSectionSystem(SECTION_SYSTEM_LOINC)
194                                .withSectionCode(SECTION_CODE_ALLERGY_INTOLERANCE)
195                                .withSectionDisplay("Allergies and adverse reactions Document")
196                                .withResourceType(AllergyIntolerance.class)
197                                .withProfile(
198                                                "https://hl7.org/fhir/uv/ips/StructureDefinition-Composition-uv-ips-definitions.html#Composition.section:sectionAllergies")
199                                .withNoInfoGenerator(new AllergyIntoleranceNoInfoR4Generator())
200                                .build();
201
202                JpaSectionSearchStrategyCollection searchStrategyCollection = JpaSectionSearchStrategyCollection.newBuilder()
203                                .addStrategy(AllergyIntolerance.class, new AllergyIntoleranceJpaSectionSearchStrategy())
204                                .build();
205
206                addJpaSection(section, searchStrategyCollection);
207        }
208
209        protected void addJpaSectionMedicationSummary() {
210                Section section = Section.newBuilder()
211                                .withTitle("Medication List")
212                                .withSectionSystem(SECTION_SYSTEM_LOINC)
213                                .withSectionCode(SECTION_CODE_MEDICATION_SUMMARY)
214                                .withSectionDisplay("History of Medication use Narrative")
215                                .withResourceType(MedicationStatement.class)
216                                .withResourceType(MedicationRequest.class)
217                                .withResourceType(MedicationAdministration.class)
218                                .withResourceType(MedicationDispense.class)
219                                .withProfile(
220                                                "https://hl7.org/fhir/uv/ips/StructureDefinition-Composition-uv-ips-definitions.html#Composition.section:sectionMedications")
221                                .withNoInfoGenerator(new MedicationNoInfoR4Generator())
222                                .build();
223
224                JpaSectionSearchStrategyCollection searchStrategyCollection = JpaSectionSearchStrategyCollection.newBuilder()
225                                .addStrategy(
226                                                MedicationAdministration.class,
227                                                new MedicationSummaryJpaSectionSearchStrategyMedicationAdministration())
228                                .addStrategy(
229                                                MedicationDispense.class, new MedicationSummaryJpaSectionSearchStrategyMedicationDispense())
230                                .addStrategy(MedicationRequest.class, new MedicationSummaryJpaSectionSearchStrategyMedicationRequest())
231                                .addStrategy(
232                                                MedicationStatement.class, new MedicationSummaryJpaSectionSearchStrategyMedicationStatement())
233                                .build();
234
235                addJpaSection(section, searchStrategyCollection);
236        }
237
238        protected void addJpaSectionProblemList() {
239                Section section = Section.newBuilder()
240                                .withTitle("Problem List")
241                                .withSectionSystem(SECTION_SYSTEM_LOINC)
242                                .withSectionCode(SECTION_CODE_PROBLEM_LIST)
243                                .withSectionDisplay("Problem list - Reported")
244                                .withResourceType(Condition.class)
245                                .withProfile(
246                                                "https://hl7.org/fhir/uv/ips/StructureDefinition-Composition-uv-ips-definitions.html#Composition.section:sectionProblems")
247                                .withNoInfoGenerator(new ProblemNoInfoR4Generator())
248                                .build();
249
250                JpaSectionSearchStrategyCollection searchStrategyCollection = JpaSectionSearchStrategyCollection.newBuilder()
251                                .addStrategy(Condition.class, new ProblemListJpaSectionSearchStrategy())
252                                .build();
253
254                addJpaSection(section, searchStrategyCollection);
255        }
256
257        protected void addJpaSectionImmunizations() {
258                Section section = Section.newBuilder()
259                                .withTitle("History of Immunizations")
260                                .withSectionSystem(SECTION_SYSTEM_LOINC)
261                                .withSectionCode(SECTION_CODE_IMMUNIZATIONS)
262                                .withSectionDisplay("History of Immunization Narrative")
263                                .withResourceType(Immunization.class)
264                                .withProfile(
265                                                "https://hl7.org/fhir/uv/ips/StructureDefinition-Composition-uv-ips-definitions.html#Composition.section:sectionImmunizations")
266                                .build();
267
268                JpaSectionSearchStrategyCollection searchStrategyCollection = JpaSectionSearchStrategyCollection.newBuilder()
269                                .addStrategy(Immunization.class, new ImmunizationsJpaSectionSearchStrategy())
270                                .build();
271
272                addJpaSection(section, searchStrategyCollection);
273        }
274
275        protected void addJpaSectionProcedures() {
276                Section section = Section.newBuilder()
277                                .withTitle("History of Procedures")
278                                .withSectionSystem(SECTION_SYSTEM_LOINC)
279                                .withSectionCode(SECTION_CODE_PROCEDURES)
280                                .withSectionDisplay("History of Procedures Document")
281                                .withResourceType(Procedure.class)
282                                .withProfile(
283                                                "https://hl7.org/fhir/uv/ips/StructureDefinition-Composition-uv-ips-definitions.html#Composition.section:sectionProceduresHx")
284                                .build();
285
286                JpaSectionSearchStrategyCollection searchStrategyCollection = JpaSectionSearchStrategyCollection.newBuilder()
287                                .addStrategy(Procedure.class, new ProceduresJpaSectionSearchStrategy())
288                                .build();
289
290                addJpaSection(section, searchStrategyCollection);
291        }
292
293        protected void addJpaSectionMedicalDevices() {
294                Section section = Section.newBuilder()
295                                .withTitle("Medical Devices")
296                                .withSectionSystem(SECTION_SYSTEM_LOINC)
297                                .withSectionCode(SECTION_CODE_MEDICAL_DEVICES)
298                                .withSectionDisplay("History of medical device use")
299                                .withResourceType(DeviceUseStatement.class)
300                                .withProfile(
301                                                "https://hl7.org/fhir/uv/ips/StructureDefinition-Composition-uv-ips-definitions.html#Composition.section:sectionMedicalDevices")
302                                .build();
303
304                JpaSectionSearchStrategyCollection searchStrategyCollection = JpaSectionSearchStrategyCollection.newBuilder()
305                                .addStrategy(DeviceUseStatement.class, new MedicalDevicesJpaSectionSearchStrategy())
306                                .build();
307
308                addJpaSection(section, searchStrategyCollection);
309        }
310
311        protected void addJpaSectionDiagnosticResults() {
312                Section section = Section.newBuilder()
313                                .withTitle("Diagnostic Results")
314                                .withSectionSystem(SECTION_SYSTEM_LOINC)
315                                .withSectionCode(SECTION_CODE_DIAGNOSTIC_RESULTS)
316                                .withSectionDisplay("Relevant diagnostic tests/laboratory data Narrative")
317                                .withResourceType(DiagnosticReport.class)
318                                .withResourceType(Observation.class)
319                                .withProfile(
320                                                "https://hl7.org/fhir/uv/ips/StructureDefinition-Composition-uv-ips-definitions.html#Composition.section:sectionResults")
321                                .build();
322
323                JpaSectionSearchStrategyCollection searchStrategyCollection = JpaSectionSearchStrategyCollection.newBuilder()
324                                .addStrategy(DiagnosticReport.class, new DiagnosticResultsJpaSectionSearchStrategyDiagnosticReport())
325                                .addStrategy(Observation.class, new DiagnosticResultsJpaSectionSearchStrategyObservation())
326                                .build();
327
328                addJpaSection(section, searchStrategyCollection);
329        }
330
331        protected void addJpaSectionVitalSigns() {
332                Section section = Section.newBuilder()
333                                .withTitle("Vital Signs")
334                                .withSectionSystem(SECTION_SYSTEM_LOINC)
335                                .withSectionCode(SECTION_CODE_VITAL_SIGNS)
336                                .withSectionDisplay("Vital signs")
337                                .withResourceType(Observation.class)
338                                .withProfile(
339                                                "https://hl7.org/fhir/uv/ips/StructureDefinition-Composition-uv-ips-definitions.html#Composition.section:sectionVitalSigns")
340                                .build();
341
342                JpaSectionSearchStrategyCollection searchStrategyCollection = JpaSectionSearchStrategyCollection.newBuilder()
343                                .addStrategy(Observation.class, new VitalSignsJpaSectionSearchStrategy())
344                                .build();
345
346                addJpaSection(section, searchStrategyCollection);
347        }
348
349        protected void addJpaSectionPregnancy() {
350                Section section = Section.newBuilder()
351                                .withTitle("Pregnancy Information")
352                                .withSectionSystem(SECTION_SYSTEM_LOINC)
353                                .withSectionCode(SECTION_CODE_PREGNANCY)
354                                .withSectionDisplay("History of pregnancies Narrative")
355                                .withResourceType(Observation.class)
356                                .withProfile(
357                                                "https://hl7.org/fhir/uv/ips/StructureDefinition-Composition-uv-ips-definitions.html#Composition.section:sectionPregnancyHx")
358                                .build();
359
360                JpaSectionSearchStrategyCollection searchStrategyCollection = JpaSectionSearchStrategyCollection.newBuilder()
361                                .addStrategy(Observation.class, new PregnancyJpaSectionSearchStrategy())
362                                .build();
363
364                addJpaSection(section, searchStrategyCollection);
365        }
366
367        protected void addJpaSectionSocialHistory() {
368                Section section = Section.newBuilder()
369                                .withTitle("Social History")
370                                .withSectionSystem(SECTION_SYSTEM_LOINC)
371                                .withSectionCode(SECTION_CODE_SOCIAL_HISTORY)
372                                .withSectionDisplay("Social history Narrative")
373                                .withResourceType(Observation.class)
374                                .withProfile(
375                                                "https://hl7.org/fhir/uv/ips/StructureDefinition-Composition-uv-ips-definitions.html#Composition.section:sectionSocialHistory")
376                                .build();
377
378                JpaSectionSearchStrategyCollection searchStrategyCollection = JpaSectionSearchStrategyCollection.newBuilder()
379                                .addStrategy(Observation.class, new SocialHistoryJpaSectionSearchStrategy())
380                                .build();
381
382                addJpaSection(section, searchStrategyCollection);
383        }
384
385        protected void addJpaSectionIllnessHistory() {
386                Section section = Section.newBuilder()
387                                .withTitle("History of Past Illness")
388                                .withSectionSystem(SECTION_SYSTEM_LOINC)
389                                .withSectionCode(SECTION_CODE_ILLNESS_HISTORY)
390                                .withSectionDisplay("History of Past illness Narrative")
391                                .withResourceType(Condition.class)
392                                .withProfile(
393                                                "https://hl7.org/fhir/uv/ips/StructureDefinition-Composition-uv-ips-definitions.html#Composition.section:sectionPastIllnessHx")
394                                .build();
395
396                JpaSectionSearchStrategyCollection searchStrategyCollection = JpaSectionSearchStrategyCollection.newBuilder()
397                                .addStrategy(Condition.class, new IllnessHistoryJpaSectionSearchStrategy())
398                                .build();
399
400                addJpaSection(section, searchStrategyCollection);
401        }
402
403        protected void addJpaSectionFunctionalStatus() {
404                Section section = Section.newBuilder()
405                                .withTitle("Functional Status")
406                                .withSectionSystem(SECTION_SYSTEM_LOINC)
407                                .withSectionCode(SECTION_CODE_FUNCTIONAL_STATUS)
408                                .withSectionDisplay("Functional status assessment note")
409                                .withResourceType(ClinicalImpression.class)
410                                .withProfile(
411                                                "https://hl7.org/fhir/uv/ips/StructureDefinition-Composition-uv-ips-definitions.html#Composition.section:sectionFunctionalStatus")
412                                .build();
413
414                JpaSectionSearchStrategyCollection searchStrategyCollection = JpaSectionSearchStrategyCollection.newBuilder()
415                                .addStrategy(ClinicalImpression.class, new FunctionalStatusJpaSectionSearchStrategy())
416                                .build();
417
418                addJpaSection(section, searchStrategyCollection);
419        }
420
421        protected void addJpaSectionPlanOfCare() {
422                Section section = Section.newBuilder()
423                                .withTitle("Plan of Care")
424                                .withSectionSystem(SECTION_SYSTEM_LOINC)
425                                .withSectionCode(SECTION_CODE_PLAN_OF_CARE)
426                                .withSectionDisplay("Plan of care note")
427                                .withResourceType(CarePlan.class)
428                                .withProfile(
429                                                "https://hl7.org/fhir/uv/ips/StructureDefinition-Composition-uv-ips-definitions.html#Composition.section:sectionPlanOfCare")
430                                .build();
431
432                JpaSectionSearchStrategyCollection searchStrategyCollection = JpaSectionSearchStrategyCollection.newBuilder()
433                                .addStrategy(CarePlan.class, new PlanOfCareJpaSectionSearchStrategy())
434                                .build();
435
436                addJpaSection(section, searchStrategyCollection);
437        }
438
439        protected void addJpaSectionAdvanceDirectives() {
440                Section section = Section.newBuilder()
441                                .withTitle("Advance Directives")
442                                .withSectionSystem(SECTION_SYSTEM_LOINC)
443                                .withSectionCode(SECTION_CODE_ADVANCE_DIRECTIVES)
444                                .withSectionDisplay("Advance directives")
445                                .withResourceType(Consent.class)
446                                .withProfile(
447                                                "https://hl7.org/fhir/uv/ips/StructureDefinition-Composition-uv-ips-definitions.html#Composition.section:sectionAdvanceDirectives")
448                                .build();
449
450                JpaSectionSearchStrategyCollection searchStrategyCollection = JpaSectionSearchStrategyCollection.newBuilder()
451                                .addStrategy(Consent.class, new AdvanceDirectivesJpaSectionSearchStrategy())
452                                .build();
453
454                addJpaSection(section, searchStrategyCollection);
455        }
456
457        protected void addJpaSection(
458                        Section theSection, JpaSectionSearchStrategyCollection theSectionSearchStrategyCollection) {
459                Section section = theSection;
460                for (var next : myGlobalSectionCustomizers) {
461                        section = next.apply(section);
462                }
463
464                Validate.isTrue(
465                                theSection.getResourceTypes().size()
466                                                == theSectionSearchStrategyCollection.getResourceTypes().size(),
467                                "Search strategy types does not match section types");
468                Validate.isTrue(
469                                new HashSet<>(theSection.getResourceTypes())
470                                                .containsAll(theSectionSearchStrategyCollection.getResourceTypes()),
471                                "Search strategy types does not match section types");
472
473                addSection(
474                                section,
475                                new JpaSectionResourceSupplier(theSectionSearchStrategyCollection, myDaoRegistry, myFhirContext));
476        }
477}