
001package ca.uhn.fhir.jpa.provider.dstu3; 002 003/* 004 * #%L 005 * HAPI FHIR JPA Server 006 * %% 007 * Copyright (C) 2014 - 2022 Smile CDR, Inc. 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import ca.uhn.fhir.i18n.Msg; 024import ca.uhn.fhir.context.support.TranslateConceptResults; 025import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoConceptMap; 026import ca.uhn.fhir.jpa.api.model.TranslationRequest; 027import ca.uhn.fhir.jpa.model.util.JpaConstants; 028import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl; 029import ca.uhn.fhir.rest.annotation.IdParam; 030import ca.uhn.fhir.rest.annotation.Operation; 031import ca.uhn.fhir.rest.annotation.OperationParam; 032import ca.uhn.fhir.rest.api.server.RequestDetails; 033import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; 034import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; 035import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40; 036import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40; 037import org.hl7.fhir.dstu3.model.BooleanType; 038import org.hl7.fhir.dstu3.model.CodeType; 039import org.hl7.fhir.dstu3.model.CodeableConcept; 040import org.hl7.fhir.dstu3.model.Coding; 041import org.hl7.fhir.dstu3.model.ConceptMap; 042import org.hl7.fhir.dstu3.model.IdType; 043import org.hl7.fhir.dstu3.model.Parameters; 044import org.hl7.fhir.dstu3.model.StringType; 045import org.hl7.fhir.dstu3.model.UriType; 046import org.hl7.fhir.exceptions.FHIRException; 047 048import javax.servlet.http.HttpServletRequest; 049 050public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderDstu3<ConceptMap> { 051 @Operation(name = JpaConstants.OPERATION_TRANSLATE, idempotent = true, returnParameters = { 052 @OperationParam(name = "result", type = BooleanType.class, min = 1, max = 1), 053 @OperationParam(name = "message", type = StringType.class, min = 0, max = 1), 054 }) 055 public Parameters translate( 056 HttpServletRequest theServletRequest, 057 @IdParam(optional = true) IdType theId, 058 @OperationParam(name = "url", min = 0, max = 1) UriType theUrl, 059 @OperationParam(name = "conceptMapVersion", min = 0, max = 1) StringType theConceptMapVersion, 060 @OperationParam(name = "code", min = 0, max = 1) CodeType theSourceCode, 061 @OperationParam(name = "system", min = 0, max = 1) UriType theSourceCodeSystem, 062 @OperationParam(name = "version", min = 0, max = 1) StringType theSourceCodeSystemVersion, 063 @OperationParam(name = "source", min = 0, max = 1) UriType theSourceValueSet, 064 @OperationParam(name = "coding", min = 0, max = 1) Coding theSourceCoding, 065 @OperationParam(name = "codeableConcept", min = 0, max = 1) CodeableConcept theSourceCodeableConcept, 066 @OperationParam(name = "target", min = 0, max = 1) UriType theTargetValueSet, 067 @OperationParam(name = "targetsystem", min = 0, max = 1) UriType theTargetCodeSystem, 068 @OperationParam(name = "reverse", min = 0, max = 1) BooleanType theReverse, 069 RequestDetails theRequestDetails 070 ) { 071 boolean haveUrl = theUrl != null 072 && theUrl.hasValue(); 073 boolean haveConceptMapVersion = theConceptMapVersion != null 074 && theConceptMapVersion.hasValue(); 075 boolean haveSourceCode = theSourceCode != null 076 && theSourceCode.hasValue(); 077 boolean haveSourceCodeSystem = theSourceCodeSystem != null 078 && theSourceCodeSystem.hasValue(); 079 boolean haveSourceCodeSystemVersion = theSourceCodeSystemVersion != null 080 && theSourceCodeSystemVersion.hasValue(); 081 boolean haveSourceValueSet = theSourceValueSet != null 082 && theSourceValueSet.hasValue(); 083 boolean haveSourceCoding = theSourceCoding != null 084 && theSourceCoding.hasCode(); 085 boolean haveSourceCodeableConcept = theSourceCodeableConcept != null 086 && theSourceCodeableConcept.hasCoding() 087 && theSourceCodeableConcept.getCodingFirstRep().hasCode(); 088 boolean haveTargetValueSet = theTargetValueSet != null 089 && theTargetValueSet.hasValue(); 090 boolean haveTargetCodeSystem = theTargetCodeSystem != null 091 && theTargetCodeSystem.hasValue(); 092 boolean haveReverse = theReverse != null; 093 boolean haveId = theId != null && theId.hasIdPart(); 094 095 // <editor-fold desc="Filters"> 096 if ((!haveSourceCode && !haveSourceCoding && !haveSourceCodeableConcept) 097 || moreThanOneTrue(haveSourceCode, haveSourceCoding, haveSourceCodeableConcept)) { 098 throw new InvalidRequestException(Msg.code(1149) + "One (and only one) of the in parameters (code, coding, codeableConcept) must be provided, to identify the code that is to be translated."); 099 } 100 101 TranslationRequest translationRequest = new TranslationRequest(); 102 try { 103 104 if (haveUrl) { 105 translationRequest.setUrl((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_30_40.convertType(theUrl, new BaseAdvisor_30_40(false))); 106 } 107 108 if (haveConceptMapVersion) { 109 translationRequest.setConceptMapVersion((org.hl7.fhir.r4.model.StringType) VersionConvertorFactory_30_40.convertType(theConceptMapVersion, new BaseAdvisor_30_40(false))); 110 } 111 112 // Convert from DSTU3 to R4 113 if (haveSourceCode) { 114 translationRequest.getCodeableConcept().addCoding().setCodeElement((org.hl7.fhir.r4.model.CodeType) VersionConvertorFactory_30_40.convertType(theSourceCode, new BaseAdvisor_30_40(false))); 115 116 if (haveSourceCodeSystem) { 117 translationRequest.getCodeableConcept().getCodingFirstRep().setSystemElement((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_30_40.convertType(theSourceCodeSystem, new BaseAdvisor_30_40(false))); 118 } 119 120 if (haveSourceCodeSystemVersion) { 121 translationRequest.getCodeableConcept().getCodingFirstRep().setVersionElement((org.hl7.fhir.r4.model.StringType) VersionConvertorFactory_30_40.convertType(theSourceCodeSystemVersion, new BaseAdvisor_30_40(false))); 122 } 123 } else if (haveSourceCoding) { 124 translationRequest.getCodeableConcept().addCoding((org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_30_40.convertType(theSourceCoding, new BaseAdvisor_30_40(false))); 125 } else { 126 translationRequest.setCodeableConcept((org.hl7.fhir.r4.model.CodeableConcept) VersionConvertorFactory_30_40.convertType(theSourceCodeableConcept, new BaseAdvisor_30_40(false))); 127 } 128 129 if (haveSourceValueSet) { 130 translationRequest.setSource((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_30_40.convertType(theSourceValueSet, new BaseAdvisor_30_40(false))); 131 } 132 133 if (haveTargetValueSet) { 134 translationRequest.setTarget((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_30_40.convertType(theTargetValueSet, new BaseAdvisor_30_40(false))); 135 } 136 137 if (haveTargetCodeSystem) { 138 translationRequest.setTargetSystem((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_30_40.convertType(theTargetCodeSystem, new BaseAdvisor_30_40(false))); 139 } 140 141 if (haveReverse) { 142 translationRequest.setReverse((org.hl7.fhir.r4.model.BooleanType) VersionConvertorFactory_30_40.convertType(theReverse, new BaseAdvisor_30_40(false))); 143 } 144 145 if (haveId) { 146 translationRequest.setResourceId(theId.getIdPartAsLong()); 147 } 148 } catch (FHIRException fe) { 149 throw new InternalErrorException(Msg.code(1150) + fe); 150 } 151 152 startRequest(theServletRequest); 153 try { 154 IFhirResourceDaoConceptMap<ConceptMap> dao = (IFhirResourceDaoConceptMap<ConceptMap>) getDao(); 155 TranslateConceptResults result = dao.translate(translationRequest, theRequestDetails); 156 157 // Convert from R4 to DSTU3 158 return (Parameters) VersionConvertorFactory_30_40.convertResource(TermConceptMappingSvcImpl.toParameters(result), new BaseAdvisor_30_40(false)); 159 } catch (FHIRException fe) { 160 throw new InternalErrorException(Msg.code(1151) + fe); 161 } finally { 162 endRequest(theServletRequest); 163 } 164 } 165 166 private static boolean moreThanOneTrue(boolean... theBooleans) { 167 boolean haveOne = false; 168 for (boolean next : theBooleans) { 169 if (next) { 170 if (haveOne) { 171 return true; 172 } else { 173 haveOne = true; 174 } 175 } 176 } 177 return false; 178 } 179}