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( 027 FhirContext fhirContext, IValidationSupport.TranslateCodeRequest theRequest) { 028 IBaseParameters params = ParametersUtil.newInstance(fhirContext); 029 if (!StringUtils.isEmpty(theRequest.getConceptMapUrl())) { 030 ParametersUtil.addParameterToParametersUri(fhirContext, params, "url", theRequest.getConceptMapUrl()); 031 } 032 if (!StringUtils.isEmpty(theRequest.getConceptMapVersion())) { 033 ParametersUtil.addParameterToParametersString( 034 fhirContext, params, "conceptMapVersion", theRequest.getConceptMapVersion()); 035 } 036 if (theRequest.getCodings() != null) { 037 addCodingsToTranslateParameters(fhirContext, theRequest.getCodings(), params); 038 } 039 if (!StringUtils.isEmpty(theRequest.getSourceValueSetUrl())) { 040 ParametersUtil.addParameterToParametersUri( 041 fhirContext, params, "source", theRequest.getSourceValueSetUrl()); 042 } 043 if (!StringUtils.isEmpty(theRequest.getTargetValueSetUrl())) { 044 ParametersUtil.addParameterToParametersUri( 045 fhirContext, params, "target", theRequest.getTargetValueSetUrl()); 046 } 047 if (!StringUtils.isEmpty(theRequest.getTargetSystemUrl())) { 048 ParametersUtil.addParameterToParametersUri( 049 fhirContext, params, "targetsystem", theRequest.getTargetSystemUrl()); 050 } 051 if (theRequest.isReverse()) { 052 ParametersUtil.addParameterToParametersBoolean(fhirContext, params, "reverse", theRequest.isReverse()); 053 } 054 055 return params; 056 } 057 058 public static void addCodingsToTranslateParameters( 059 FhirContext fhirContext, List<IBaseCoding> theCodings, IBaseParameters theParams) { 060 BaseRuntimeElementCompositeDefinition<?> codeableConceptDef = (BaseRuntimeElementCompositeDefinition<?>) 061 Objects.requireNonNull(fhirContext.getElementDefinition("CodeableConcept")); 062 BaseRuntimeChildDefinition codings = codeableConceptDef.getChildByName("coding"); 063 BaseRuntimeElementCompositeDefinition<?> codingDef = (BaseRuntimeElementCompositeDefinition<?>) 064 Objects.requireNonNull(fhirContext.getElementDefinition("Coding")); 065 BaseRuntimeChildDefinition codingSystemChild = codingDef.getChildByName("system"); 066 BaseRuntimeChildDefinition codingCodeChild = codingDef.getChildByName("code"); 067 BaseRuntimeElementDefinition<IPrimitiveType<?>> systemDef = 068 (RuntimePrimitiveDatatypeDefinition) fhirContext.getElementDefinition("uri"); 069 BaseRuntimeElementDefinition<IPrimitiveType<?>> codeDef = 070 (RuntimePrimitiveDatatypeDefinition) fhirContext.getElementDefinition("code"); 071 072 IBase codeableConcept = codeableConceptDef.newInstance(); 073 074 for (IBaseCoding aCoding : theCodings) { 075 IBaseCoding newCoding = (IBaseCoding) codingDef.newInstance(); 076 077 IPrimitiveType<?> newSystem = systemDef.newInstance(aCoding.getSystem()); 078 codingSystemChild.getMutator().addValue(newCoding, newSystem); 079 IPrimitiveType<?> newCode = codeDef.newInstance(aCoding.getCode()); 080 codingCodeChild.getMutator().addValue(newCoding, newCode); 081 082 codings.getMutator().addValue(codeableConcept, newCoding); 083 } 084 085 ParametersUtil.addParameterToParameters(fhirContext, theParams, "codeableConcept", codeableConcept); 086 } 087 088 public static TranslateConceptResults translateOutcomeToResults(FhirContext fhirContext, IBaseParameters outcome) { 089 Optional<String> result = ParametersUtil.getNamedParameterValueAsString(fhirContext, outcome, "result"); 090 Optional<String> message = ParametersUtil.getNamedParameterValueAsString(fhirContext, outcome, "message"); 091 List<IBase> matches = ParametersUtil.getNamedParameters(fhirContext, outcome, "match"); 092 093 TranslateConceptResults retVal = new TranslateConceptResults(); 094 if (result.isPresent()) { 095 retVal.setResult(Boolean.parseBoolean(result.get())); 096 } 097 if (message.isPresent()) { 098 retVal.setMessage(message.get()); 099 } 100 if (!matches.isEmpty()) { 101 retVal.setResults(matchesToTranslateConceptResults(fhirContext, matches)); 102 } 103 104 return retVal; 105 } 106 107 private static List<TranslateConceptResult> matchesToTranslateConceptResults( 108 FhirContext fhirContext, List<IBase> theMatches) { 109 List<TranslateConceptResult> resultList = new ArrayList(); 110 for (IBase m : theMatches) { 111 TranslateConceptResult match = new TranslateConceptResult(); 112 String equivalence = ParametersUtil.getParameterPartValueAsString(fhirContext, m, "equivalence"); 113 Optional<IBase> concept = ParametersUtil.getParameterPartValue(fhirContext, m, "concept"); 114 String source = ParametersUtil.getParameterPartValueAsString(fhirContext, m, "source"); 115 116 if (StringUtils.isNotBlank(equivalence)) { 117 match.setEquivalence(equivalence); 118 } 119 120 if (concept.isPresent()) { 121 IBaseCoding matchedCoding = (IBaseCoding) concept.get(); 122 match.setSystem(matchedCoding.getSystem()); 123 match.setCode(matchedCoding.getCode()); 124 match.setDisplay(matchedCoding.getDisplay()); 125 126 if (StringUtils.isNotBlank(source)) { 127 match.setConceptMapUrl(source); 128 } 129 130 resultList.add(match); 131 } 132 } 133 return resultList; 134 } 135}