add `displayLanguage` to the `ValueSet/$expand` (#3619)
* add `displayLanguage` to the `ValueSet/$expand` * fix tests * fix tests
This commit is contained in:
parent
f0decbf8c8
commit
4684dde6a6
|
@ -35,6 +35,8 @@ public class ValueSetExpansionOptions {
|
||||||
private boolean myIncludeHierarchy;
|
private boolean myIncludeHierarchy;
|
||||||
private String myFilter;
|
private String myFilter;
|
||||||
|
|
||||||
|
private String myDisplayLanguage;
|
||||||
|
|
||||||
public String getFilter() {
|
public String getFilter() {
|
||||||
return myFilter;
|
return myFilter;
|
||||||
}
|
}
|
||||||
|
@ -118,4 +120,13 @@ public class ValueSetExpansionOptions {
|
||||||
.setOffset(theOffset)
|
.setOffset(theOffset)
|
||||||
.setCount(theCount);
|
.setCount(theCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTheDisplayLanguage() {
|
||||||
|
return myDisplayLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueSetExpansionOptions setTheDisplayLanguage(String theDisplayLanguage) {
|
||||||
|
myDisplayLanguage = theDisplayLanguage;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,11 +50,13 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.ICompositeType;
|
import org.hl7.fhir.instance.model.api.ICompositeType;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
import org.hl7.fhir.r4.model.CodeType;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
@ -108,6 +110,7 @@ public class ValueSetOperationProvider extends BaseJpaProvider {
|
||||||
@OperationParam(name = "contextDirection", min = 0, max = 1, typeName = "string") IPrimitiveType<String> theContextDirection,
|
@OperationParam(name = "contextDirection", min = 0, max = 1, typeName = "string") IPrimitiveType<String> theContextDirection,
|
||||||
@OperationParam(name = "offset", min = 0, max = 1, typeName = "integer") IPrimitiveType<Integer> theOffset,
|
@OperationParam(name = "offset", min = 0, max = 1, typeName = "integer") IPrimitiveType<Integer> theOffset,
|
||||||
@OperationParam(name = "count", min = 0, max = 1, typeName = "integer") IPrimitiveType<Integer> theCount,
|
@OperationParam(name = "count", min = 0, max = 1, typeName = "integer") IPrimitiveType<Integer> theCount,
|
||||||
|
@OperationParam(name = JpaConstants.OPERATION_EXPAND_PARAM_DISPLAY_LANGUAGE, min = 0, max = 1, typeName = "code") IPrimitiveType<String> theDisplayLanguage,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPAND_PARAM_INCLUDE_HIERARCHY, min = 0, max = 1, typeName = "boolean") IPrimitiveType<Boolean> theIncludeHierarchy,
|
@OperationParam(name = JpaConstants.OPERATION_EXPAND_PARAM_INCLUDE_HIERARCHY, min = 0, max = 1, typeName = "boolean") IPrimitiveType<Boolean> theIncludeHierarchy,
|
||||||
RequestDetails theRequestDetails) {
|
RequestDetails theRequestDetails) {
|
||||||
|
|
||||||
|
@ -143,7 +146,7 @@ public class ValueSetOperationProvider extends BaseJpaProvider {
|
||||||
throw new InvalidRequestException(Msg.code(1134) + "$expand must EITHER be invoked at the instance level, or have a url specified, or have a ValueSet specified. Can not combine these options.");
|
throw new InvalidRequestException(Msg.code(1134) + "$expand must EITHER be invoked at the instance level, or have a url specified, or have a ValueSet specified. Can not combine these options.");
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueSetExpansionOptions options = createValueSetExpansionOptions(myDaoConfig, theOffset, theCount, theIncludeHierarchy, theFilter);
|
ValueSetExpansionOptions options = createValueSetExpansionOptions(myDaoConfig, theOffset, theCount, theIncludeHierarchy, theFilter, theDisplayLanguage);
|
||||||
|
|
||||||
startRequest(theServletRequest);
|
startRequest(theServletRequest);
|
||||||
try {
|
try {
|
||||||
|
@ -265,7 +268,7 @@ public class ValueSetOperationProvider extends BaseJpaProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static ValueSetExpansionOptions createValueSetExpansionOptions(DaoConfig theDaoConfig, IPrimitiveType<Integer> theOffset, IPrimitiveType<Integer> theCount, IPrimitiveType<Boolean> theIncludeHierarchy, IPrimitiveType<String> theFilter) {
|
public static ValueSetExpansionOptions createValueSetExpansionOptions(DaoConfig theDaoConfig, IPrimitiveType<Integer> theOffset, IPrimitiveType<Integer> theCount, IPrimitiveType<Boolean> theIncludeHierarchy, IPrimitiveType<String> theFilter, IPrimitiveType<String> theDisplayLanguage) {
|
||||||
int offset = theDaoConfig.getPreExpandValueSetsDefaultOffset();
|
int offset = theDaoConfig.getPreExpandValueSetsDefaultOffset();
|
||||||
if (theOffset != null && theOffset.hasValue()) {
|
if (theOffset != null && theOffset.hasValue()) {
|
||||||
if (theOffset.getValue() >= 0) {
|
if (theOffset.getValue() >= 0) {
|
||||||
|
@ -299,6 +302,10 @@ public class ValueSetOperationProvider extends BaseJpaProvider {
|
||||||
options.setFilter(theFilter.getValue());
|
options.setFilter(theFilter.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( theDisplayLanguage != null ) {
|
||||||
|
options.setTheDisplayLanguage(theDisplayLanguage.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -308,6 +308,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
||||||
.collect(joining(" "));
|
.collect(joining(" "));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Collection<TermConceptDesignation> designations = theConcept.getDesignations();
|
Collection<TermConceptDesignation> designations = theConcept.getDesignations();
|
||||||
if (StringUtils.isNotEmpty(theValueSetIncludeVersion)) {
|
if (StringUtils.isNotEmpty(theValueSetIncludeVersion)) {
|
||||||
return addCodeIfNotAlreadyAdded(theValueSetCodeAccumulator, theAddedCodes, designations, theAdd, codeSystem + "|" + theValueSetIncludeVersion, code, display, sourceConceptPid, directParentPids, codeSystemVersion);
|
return addCodeIfNotAlreadyAdded(theValueSetCodeAccumulator, theAddedCodes, designations, theAdd, codeSystem + "|" + theValueSetIncludeVersion, code, display, sourceConceptPid, directParentPids, codeSystemVersion);
|
||||||
|
@ -526,7 +527,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
||||||
String expansionTimestamp = toHumanReadableExpansionTimestamp(termValueSet);
|
String expansionTimestamp = toHumanReadableExpansionTimestamp(termValueSet);
|
||||||
String msg = myContext.getLocalizer().getMessage(BaseTermReadSvcImpl.class, "valueSetExpandedUsingPreExpansion", expansionTimestamp);
|
String msg = myContext.getLocalizer().getMessage(BaseTermReadSvcImpl.class, "valueSetExpandedUsingPreExpansion", expansionTimestamp);
|
||||||
theAccumulator.addMessage(msg);
|
theAccumulator.addMessage(msg);
|
||||||
expandConcepts(theAccumulator, termValueSet, theFilter, theAdd, isOracleDialect());
|
expandConcepts(theExpansionOptions, theAccumulator, termValueSet, theFilter, theAdd, isOracleDialect());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
@ -543,7 +544,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
||||||
return myHibernatePropertiesProvider.getDialect() instanceof org.hibernate.dialect.Oracle12cDialect;
|
return myHibernatePropertiesProvider.getDialect() instanceof org.hibernate.dialect.Oracle12cDialect;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expandConcepts(IValueSetConceptAccumulator theAccumulator, TermValueSet theTermValueSet, ExpansionFilter theFilter, boolean theAdd, boolean theOracle) {
|
private void expandConcepts(ValueSetExpansionOptions theExpansionOptions, IValueSetConceptAccumulator theAccumulator, TermValueSet theTermValueSet, ExpansionFilter theFilter, boolean theAdd, boolean theOracle) {
|
||||||
// NOTE: if you modifiy the logic here, look to `expandConceptsOracle` and see if your new code applies to its copy pasted sibling
|
// NOTE: if you modifiy the logic here, look to `expandConceptsOracle` and see if your new code applies to its copy pasted sibling
|
||||||
Integer offset = theAccumulator.getSkipCountRemaining();
|
Integer offset = theAccumulator.getSkipCountRemaining();
|
||||||
offset = ObjectUtils.defaultIfNull(offset, 0);
|
offset = ObjectUtils.defaultIfNull(offset, 0);
|
||||||
|
@ -612,12 +613,15 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
||||||
// TODO: DM 2019-08-17 - Implement includeDesignations parameter for $expand operation to designations optional.
|
// TODO: DM 2019-08-17 - Implement includeDesignations parameter for $expand operation to designations optional.
|
||||||
if (conceptView.getDesignationPid() != null) {
|
if (conceptView.getDesignationPid() != null) {
|
||||||
TermConceptDesignation designation = new TermConceptDesignation();
|
TermConceptDesignation designation = new TermConceptDesignation();
|
||||||
designation.setUseSystem(conceptView.getDesignationUseSystem());
|
|
||||||
designation.setUseCode(conceptView.getDesignationUseCode());
|
if(isValueSetDisplayLanguageMatch(theExpansionOptions, conceptView.getDesignationLang() )) {
|
||||||
designation.setUseDisplay(conceptView.getDesignationUseDisplay());
|
designation.setUseSystem(conceptView.getDesignationUseSystem());
|
||||||
designation.setValue(conceptView.getDesignationVal());
|
designation.setUseCode(conceptView.getDesignationUseCode());
|
||||||
designation.setLanguage(conceptView.getDesignationLang());
|
designation.setUseDisplay(conceptView.getDesignationUseDisplay());
|
||||||
pidToDesignations.put(conceptPid, designation);
|
designation.setValue(conceptView.getDesignationVal());
|
||||||
|
designation.setLanguage(conceptView.getDesignationLang());
|
||||||
|
pidToDesignations.put(conceptPid, designation);
|
||||||
|
}
|
||||||
|
|
||||||
if (++designationsExpanded % 250 == 0) {
|
if (++designationsExpanded % 250 == 0) {
|
||||||
logDesignationsExpanded("Expansion of designations in progress. ", theTermValueSet, designationsExpanded);
|
logDesignationsExpanded("Expansion of designations in progress. ", theTermValueSet, designationsExpanded);
|
||||||
|
@ -668,6 +672,19 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
|
||||||
logConceptsExpanded("Finished expanding concepts. ", theTermValueSet, conceptsExpanded);
|
logConceptsExpanded("Finished expanding concepts. ", theTermValueSet, conceptsExpanded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean isValueSetDisplayLanguageMatch(ValueSetExpansionOptions theExpansionOptions, String theStoredLang){
|
||||||
|
if( theExpansionOptions == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(theExpansionOptions.getTheDisplayLanguage() == null || theStoredLang == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return theExpansionOptions.getTheDisplayLanguage().equalsIgnoreCase(theStoredLang);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void logConceptsExpanded(String theLogDescriptionPrefix, TermValueSet theTermValueSet, int theConceptsExpanded) {
|
private void logConceptsExpanded(String theLogDescriptionPrefix, TermValueSet theTermValueSet, int theConceptsExpanded) {
|
||||||
if (theConceptsExpanded > 0) {
|
if (theConceptsExpanded > 0) {
|
||||||
ourLog.debug("{}Have expanded {} concepts in ValueSet[{}]", theLogDescriptionPrefix, theConceptsExpanded, theTermValueSet.getUrl());
|
ourLog.debug("{}Have expanded {} concepts in ValueSet[{}]", theLogDescriptionPrefix, theConceptsExpanded, theTermValueSet.getUrl());
|
||||||
|
|
|
@ -257,9 +257,11 @@ public class JpaConstants {
|
||||||
* Parameter for the $expand operation
|
* Parameter for the $expand operation
|
||||||
*/
|
*/
|
||||||
public static final String OPERATION_EXPAND_PARAM_INCLUDE_HIERARCHY = "includeHierarchy";
|
public static final String OPERATION_EXPAND_PARAM_INCLUDE_HIERARCHY = "includeHierarchy";
|
||||||
|
public static final String OPERATION_EXPAND_PARAM_DISPLAY_LANGUAGE = "displayLanguage";
|
||||||
public static final String HEADER_UPSERT_EXISTENCE_CHECK = "X-Upsert-Extistence-Check";
|
public static final String HEADER_UPSERT_EXISTENCE_CHECK = "X-Upsert-Extistence-Check";
|
||||||
public static final String HEADER_UPSERT_EXISTENCE_CHECK_DISABLED = "disabled";
|
public static final String HEADER_UPSERT_EXISTENCE_CHECK_DISABLED = "disabled";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parameters for the rewrite history operation
|
* Parameters for the rewrite history operation
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -630,6 +630,46 @@ public class ValueSetExpansionR4Test extends BaseTermR4Test {
|
||||||
assertExpandedValueSetContainsConcept(expandedValueSet, "http://acme.org", "8492-1", "Systolic blood pressure 8 hour minimum", 0);
|
assertExpandedValueSetContainsConcept(expandedValueSet, "http://acme.org", "8492-1", "Systolic blood pressure 8 hour minimum", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExpandTermValueSetAndChildrenWithCountWithDisplayLanguage() throws Exception {
|
||||||
|
myDaoConfig.setPreExpandValueSets(true);
|
||||||
|
|
||||||
|
loadAndPersistCodeSystemAndValueSetWithDesignations(HttpVerb.POST);
|
||||||
|
|
||||||
|
CodeSystem codeSystem = myCodeSystemDao.read(myExtensionalCsId);
|
||||||
|
ourLog.info("CodeSystem:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(codeSystem));
|
||||||
|
|
||||||
|
ValueSet valueSet = myValueSetDao.read(myExtensionalVsId);
|
||||||
|
ourLog.info("ValueSet:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(valueSet));
|
||||||
|
|
||||||
|
myTermSvc.preExpandDeferredValueSetsToTerminologyTables();
|
||||||
|
|
||||||
|
List<String> expandedConceptCodes = getExpandedConceptsByValueSetUrl("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2");
|
||||||
|
|
||||||
|
ValueSetExpansionOptions options = new ValueSetExpansionOptions()
|
||||||
|
.setOffset(0)
|
||||||
|
.setCount(23)
|
||||||
|
.setTheDisplayLanguage("nl");
|
||||||
|
ValueSet expandedValueSet = myTermSvc.expandValueSet(options, valueSet);
|
||||||
|
ourLog.info("Expanded ValueSet:\n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(expandedValueSet));
|
||||||
|
|
||||||
|
assertEquals(codeSystem.getConcept().size(), expandedValueSet.getExpansion().getTotal());
|
||||||
|
assertEquals(myDaoConfig.getPreExpandValueSetsDefaultOffset(), expandedValueSet.getExpansion().getOffset());
|
||||||
|
assertEquals(2, expandedValueSet.getExpansion().getParameter().size());
|
||||||
|
assertEquals("offset", expandedValueSet.getExpansion().getParameter().get(0).getName());
|
||||||
|
assertEquals(0, expandedValueSet.getExpansion().getParameter().get(0).getValueIntegerType().getValue().intValue());
|
||||||
|
assertEquals("count", expandedValueSet.getExpansion().getParameter().get(1).getName());
|
||||||
|
assertEquals(23, expandedValueSet.getExpansion().getParameter().get(1).getValueIntegerType().getValue().intValue());
|
||||||
|
assertEquals(23, expandedValueSet.getExpansion().getContains().size());
|
||||||
|
|
||||||
|
ValueSet.ValueSetExpansionContainsComponent concept = assertExpandedValueSetContainsConcept(expandedValueSet, "http://acme.org", "8450-9", "Systolic blood pressure--expiration", 1);
|
||||||
|
assertThat(concept.getDesignation().size() , is(equalTo(1)));
|
||||||
|
assertConceptContainsDesignation(concept, "nl", "http://snomed.info/sct", "900000000000013009", "Synonym", "Systolische bloeddruk - expiratie");
|
||||||
|
|
||||||
|
//It is enough to test that the sublist returned is the correct one.
|
||||||
|
assertThat(ValueSetTestUtil.toCodes(expandedValueSet), is(equalTo(expandedConceptCodes.subList(0, 23))));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExpandTermValueSetAndChildrenWithCount() throws Exception {
|
public void testExpandTermValueSetAndChildrenWithCount() throws Exception {
|
||||||
myDaoConfig.setPreExpandValueSets(true);
|
myDaoConfig.setPreExpandValueSets(true);
|
||||||
|
|
Loading…
Reference in New Issue