001package org.hl7.fhir.common.hapi.validation.support; 002 003import ca.uhn.fhir.context.BaseRuntimeChildDefinition; 004import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; 005import ca.uhn.fhir.context.BaseRuntimeElementDefinition; 006import ca.uhn.fhir.context.FhirContext; 007import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition; 008import ca.uhn.fhir.context.support.IValidationSupport; 009import ca.uhn.fhir.context.support.TranslateConceptResult; 010import ca.uhn.fhir.context.support.TranslateConceptResults; 011import ca.uhn.fhir.util.ParametersUtil; 012import org.apache.commons.lang3.StringUtils; 013import org.hl7.fhir.instance.model.api.IBase; 014import org.hl7.fhir.instance.model.api.IBaseCoding; 015import org.hl7.fhir.instance.model.api.IBaseParameters; 016import org.hl7.fhir.instance.model.api.IPrimitiveType; 017 018import java.util.ArrayList; 019import java.util.List; 020import java.util.Objects; 021import java.util.Optional; 022 023public final class RemoteTerminologyUtil { 024 private RemoteTerminologyUtil() {} 025 026 public static IBaseParameters buildTranslateInputParameters(FhirContext fhirContext, IValidationSupport.TranslateCodeRequest theRequest) { 027 IBaseParameters params = ParametersUtil.newInstance(fhirContext); 028 if (!StringUtils.isEmpty(theRequest.getConceptMapUrl())) { 029 ParametersUtil.addParameterToParametersUri(fhirContext, params, "url", theRequest.getConceptMapUrl()); 030 } 031 if (!StringUtils.isEmpty(theRequest.getConceptMapVersion())) { 032 ParametersUtil.addParameterToParametersString(fhirContext, params, "conceptMapVersion", theRequest.getConceptMapVersion()); 033 } 034 if (theRequest.getCodings() != null) { 035 addCodingsToTranslateParameters(fhirContext, theRequest.getCodings(), params); 036 } 037 if (!StringUtils.isEmpty(theRequest.getSourceValueSetUrl())) { 038 ParametersUtil.addParameterToParametersUri(fhirContext, params, "source", theRequest.getSourceValueSetUrl()); 039 } 040 if (!StringUtils.isEmpty(theRequest.getTargetValueSetUrl())) { 041 ParametersUtil.addParameterToParametersUri(fhirContext, params, "target", theRequest.getTargetValueSetUrl()); 042 } 043 if (!StringUtils.isEmpty(theRequest.getTargetSystemUrl())) { 044 ParametersUtil.addParameterToParametersUri(fhirContext, params, "targetsystem", theRequest.getTargetSystemUrl()); 045 } 046 if (theRequest.isReverse()) { 047 ParametersUtil.addParameterToParametersBoolean(fhirContext, params, "reverse", theRequest.isReverse()); 048 } 049 050 return params; 051 } 052 053 public static void addCodingsToTranslateParameters(FhirContext fhirContext, List<IBaseCoding> theCodings, IBaseParameters theParams) { 054 BaseRuntimeElementCompositeDefinition<?> codeableConceptDef = (BaseRuntimeElementCompositeDefinition<?>) Objects.requireNonNull(fhirContext.getElementDefinition("CodeableConcept")); 055 BaseRuntimeChildDefinition codings = codeableConceptDef.getChildByName("coding"); 056 BaseRuntimeElementCompositeDefinition<?> codingDef = (BaseRuntimeElementCompositeDefinition<?>) Objects.requireNonNull(fhirContext.getElementDefinition("Coding")); 057 BaseRuntimeChildDefinition codingSystemChild = codingDef.getChildByName("system"); 058 BaseRuntimeChildDefinition codingCodeChild = codingDef.getChildByName("code"); 059 BaseRuntimeElementDefinition<IPrimitiveType<?>> systemDef = (RuntimePrimitiveDatatypeDefinition) fhirContext.getElementDefinition("uri"); 060 BaseRuntimeElementDefinition<IPrimitiveType<?>> codeDef = (RuntimePrimitiveDatatypeDefinition) fhirContext.getElementDefinition("code"); 061 062 IBase codeableConcept = codeableConceptDef.newInstance(); 063 064 for (IBaseCoding aCoding : theCodings) { 065 IBaseCoding newCoding = (IBaseCoding) codingDef.newInstance(); 066 067 IPrimitiveType<?> newSystem = systemDef.newInstance(aCoding.getSystem()); 068 codingSystemChild.getMutator().addValue(newCoding, newSystem); 069 IPrimitiveType<?> newCode = codeDef.newInstance(aCoding.getCode()); 070 codingCodeChild.getMutator().addValue(newCoding, newCode); 071 072 codings.getMutator().addValue(codeableConcept, newCoding); 073 } 074 075 ParametersUtil.addParameterToParameters(fhirContext, theParams, "codeableConcept", codeableConcept); 076 } 077 078 public static TranslateConceptResults translateOutcomeToResults(FhirContext fhirContext, IBaseParameters outcome) { 079 Optional<String> result = ParametersUtil.getNamedParameterValueAsString(fhirContext, outcome, "result"); 080 Optional<String> message = ParametersUtil.getNamedParameterValueAsString(fhirContext, outcome, "message"); 081 List<IBase> matches = ParametersUtil.getNamedParameters(fhirContext, outcome, "match"); 082 083 TranslateConceptResults retVal = new TranslateConceptResults(); 084 if (result.isPresent()) { 085 retVal.setResult(Boolean.parseBoolean(result.get())); 086 } 087 if (message.isPresent()) { 088 retVal.setMessage(message.get()); 089 } 090 if (!matches.isEmpty()) { 091 retVal.setResults(matchesToTranslateConceptResults(fhirContext, matches)); 092 } 093 094 return retVal; 095 } 096 097 private static List<TranslateConceptResult> matchesToTranslateConceptResults(FhirContext fhirContext, List<IBase> theMatches) { 098 List<TranslateConceptResult> resultList = new ArrayList(); 099 for (IBase m : theMatches) { 100 TranslateConceptResult match = new TranslateConceptResult(); 101 String equivalence = ParametersUtil.getParameterPartValueAsString(fhirContext, m, "equivalence"); 102 Optional<IBase> concept = ParametersUtil.getParameterPartValue(fhirContext, m, "concept"); 103 String source = ParametersUtil.getParameterPartValueAsString(fhirContext, m, "source"); 104 105 if (StringUtils.isNotBlank(equivalence)) { 106 match.setEquivalence(equivalence); 107 } 108 109 if (concept.isPresent()) { 110 IBaseCoding matchedCoding = (IBaseCoding) concept.get(); 111 match.setSystem(matchedCoding.getSystem()); 112 match.setCode(matchedCoding.getCode()); 113 match.setDisplay(matchedCoding.getDisplay()); 114 115 if (StringUtils.isNotBlank(source)) { 116 match.setConceptMapUrl(source); 117 } 118 119 resultList.add(match); 120 } 121 } 122 return resultList; 123 } 124}