001/*- 002 * #%L 003 * HAPI FHIR JPA Server 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.term; 021 022import ca.uhn.fhir.i18n.Msg; 023import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; 024import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc; 025import ca.uhn.fhir.rest.api.server.RequestDetails; 026import ca.uhn.fhir.util.UrlUtil; 027import org.hl7.fhir.instance.model.api.IIdType; 028import org.hl7.fhir.r4.model.CodeSystem; 029import org.hl7.fhir.r4.model.ConceptMap; 030import org.hl7.fhir.r4.model.ValueSet; 031import org.springframework.beans.factory.annotation.Autowired; 032import org.springframework.context.ApplicationContext; 033import org.springframework.context.event.ContextRefreshedEvent; 034import org.springframework.context.event.EventListener; 035 036import java.security.InvalidParameterException; 037 038import static org.apache.commons.lang3.StringUtils.isBlank; 039import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW; 040 041public class TermVersionAdapterSvcR4 extends BaseTermVersionAdapterSvcImpl implements ITermVersionAdapterSvc { 042 private IFhirResourceDao<ConceptMap> myConceptMapResourceDao; 043 private IFhirResourceDao<CodeSystem> myCodeSystemResourceDao; 044 private IFhirResourceDao<ValueSet> myValueSetResourceDao; 045 046 @Autowired 047 private ApplicationContext myAppCtx; 048 049 /** 050 * Initialize the beans that are used by this service. 051 * 052 * Note: There is a circular dependency here where the CodeSystem DAO 053 * needs terminology services, and the term services need the CodeSystem DAO. 054 * So we look these up in a refresh event instead of just autowiring them 055 * in order to avoid weird circular reference errors. 056 */ 057 @SuppressWarnings({"unchecked", "unused"}) 058 @EventListener 059 public void start(ContextRefreshedEvent theEvent) { 060 myCodeSystemResourceDao = (IFhirResourceDao<CodeSystem>) myAppCtx.getBean("myCodeSystemDaoR4"); 061 myValueSetResourceDao = (IFhirResourceDao<ValueSet>) myAppCtx.getBean("myValueSetDaoR4"); 062 myConceptMapResourceDao = (IFhirResourceDao<ConceptMap>) myAppCtx.getBean("myConceptMapDaoR4"); 063 } 064 065 @Override 066 public IIdType createOrUpdateCodeSystem( 067 org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource, RequestDetails theRequestDetails) { 068 validateCodeSystemForStorage(theCodeSystemResource); 069 if (isBlank(theCodeSystemResource.getIdElement().getIdPart())) { 070 if (theCodeSystemResource.getUrl().contains(LOINC_LOW)) { 071 throw new InvalidParameterException(Msg.code(859) + "'loinc' CodeSystem must have an 'ID' element"); 072 } 073 String matchUrl = "CodeSystem?url=" + UrlUtil.escapeUrlParam(theCodeSystemResource.getUrl()); 074 return myCodeSystemResourceDao 075 .update(theCodeSystemResource, matchUrl, theRequestDetails) 076 .getId(); 077 } else { 078 return myCodeSystemResourceDao 079 .update(theCodeSystemResource, theRequestDetails) 080 .getId(); 081 } 082 } 083 084 @Override 085 public void createOrUpdateConceptMap(org.hl7.fhir.r4.model.ConceptMap theConceptMap) { 086 if (isBlank(theConceptMap.getIdElement().getIdPart())) { 087 String matchUrl = "ConceptMap?url=" + UrlUtil.escapeUrlParam(theConceptMap.getUrl()); 088 myConceptMapResourceDao.update(theConceptMap, matchUrl); 089 } else { 090 myConceptMapResourceDao.update(theConceptMap); 091 } 092 } 093 094 @Override 095 public void createOrUpdateValueSet(org.hl7.fhir.r4.model.ValueSet theValueSet) { 096 if (isBlank(theValueSet.getIdElement().getIdPart())) { 097 String matchUrl = "ValueSet?url=" + UrlUtil.escapeUrlParam(theValueSet.getUrl()); 098 myValueSetResourceDao.update(theValueSet, matchUrl); 099 } else { 100 myValueSetResourceDao.update(theValueSet); 101 } 102 } 103}