001/*
002 * #%L
003 * HAPI FHIR JPA Server
004 * %%
005 * Copyright (C) 2014 - 2025 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.validation;
021
022import ca.uhn.fhir.context.FhirContext;
023import ca.uhn.fhir.context.support.IValidationSupport;
024import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
025import ca.uhn.fhir.jpa.config.JpaConfig;
026import ca.uhn.fhir.jpa.packages.NpmJpaValidationSupport;
027import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc;
028import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
029import com.google.common.annotations.VisibleForTesting;
030import jakarta.annotation.PostConstruct;
031import jakarta.annotation.PreDestroy;
032import org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService;
033import org.hl7.fhir.common.hapi.validation.support.InMemoryTerminologyServerValidationSupport;
034import org.hl7.fhir.common.hapi.validation.support.SnapshotGeneratingValidationSupport;
035import org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain;
036import org.hl7.fhir.common.hapi.validation.validator.WorkerContextValidationSupportAdapter;
037import org.springframework.beans.factory.annotation.Autowired;
038import org.springframework.beans.factory.annotation.Qualifier;
039
040public class JpaValidationSupportChain extends ValidationSupportChain {
041
042        private final FhirContext myFhirContext;
043        private final WorkerContextValidationSupportAdapter myWorkerContextValidationSupportAdapter;
044
045        @Autowired
046        @Qualifier(JpaConfig.JPA_VALIDATION_SUPPORT)
047        public IValidationSupport myJpaValidationSupport;
048
049        @Qualifier("myDefaultProfileValidationSupport")
050        @Autowired
051        private IValidationSupport myDefaultProfileValidationSupport;
052
053        @Autowired
054        private ITermReadSvc myTerminologyService;
055
056        @Autowired
057        private NpmJpaValidationSupport myNpmJpaValidationSupport;
058
059        @Autowired
060        private ITermConceptMappingSvc myConceptMappingSvc;
061
062        @Autowired
063        private InMemoryTerminologyServerValidationSupport myInMemoryTerminologyServerValidationSupport;
064
065        @Autowired
066        private JpaStorageSettings myJpaStorageSettings;
067
068        /**
069         * Constructor
070         */
071        public JpaValidationSupportChain(
072                        FhirContext theFhirContext,
073                        CacheConfiguration theCacheConfiguration,
074                        WorkerContextValidationSupportAdapter theWorkerContextValidationSupportAdapter) {
075                super(theCacheConfiguration);
076
077                assert theFhirContext != null;
078                assert theCacheConfiguration != null;
079
080                myFhirContext = theFhirContext;
081                myWorkerContextValidationSupportAdapter = theWorkerContextValidationSupportAdapter;
082        }
083
084        @Override
085        public FhirContext getFhirContext() {
086                return myFhirContext;
087        }
088
089        @PreDestroy
090        public void flush() {
091                invalidateCaches();
092        }
093
094        @PostConstruct
095        public void postConstruct() {
096                myWorkerContextValidationSupportAdapter.setValidationSupport(this);
097
098                if (myJpaStorageSettings.isAllowDatabaseValidationOverride()) {
099                        addValidationSupport(myJpaValidationSupport);
100                        addValidationSupport(myDefaultProfileValidationSupport);
101                } else {
102                        addValidationSupport(myDefaultProfileValidationSupport);
103                        addValidationSupport(myJpaValidationSupport);
104                }
105                addValidationSupport(myTerminologyService);
106                addValidationSupport(
107                                new SnapshotGeneratingValidationSupport(myFhirContext, myWorkerContextValidationSupportAdapter));
108                addValidationSupport(myInMemoryTerminologyServerValidationSupport);
109                addValidationSupport(myNpmJpaValidationSupport);
110                addValidationSupport(new CommonCodeSystemsTerminologyService(myFhirContext));
111                addValidationSupport(myConceptMappingSvc);
112        }
113
114        /**
115         * Clears and rebuilds the validation support chain.
116         * This method is intended for unit testing purposes only to allow
117         * re-initializing the chain after changing configuration settings
118         * such as {@link JpaStorageSettings#setAllowDatabaseValidationOverride(boolean)}.
119         */
120        @VisibleForTesting
121        public void rebuildChainForUnitTest() {
122                super.clearChainForUnitTest();
123                postConstruct();
124        }
125}