FHIR-25206 handle deprecated concepts properly when expanding value sets

This commit is contained in:
Grahame Grieve 2022-08-19 14:24:20 +10:00
parent fdb15b8951
commit ae285401ae
4 changed files with 139 additions and 66 deletions

View File

@ -14,6 +14,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hamcrest.beans.HasProperty;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
@ -36,6 +37,7 @@ import org.hl7.fhir.r5.model.PrimitiveType;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent;
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent;
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceDesignationComponent;
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
@ -44,6 +46,7 @@ import org.hl7.fhir.r5.model.ValueSet.ValueSetComposeComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionPropertyComponent;
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
@ -158,6 +161,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
boolean hasExtensions = false;
List<String> langs = new ArrayList<String>();
Map<String, String> designations = new HashMap<>(); // map of url = description, where url is the designation code. Designations that are for languages won't make it into this list
Map<String, String> properties = new HashMap<>(); // map of url = description, where url is the designation code. Designations that are for languages won't make it into this list
if (header) {
XhtmlNode h = x.addTag(getHeader());
@ -198,40 +202,32 @@ public class ValueSetRenderer extends TerminologyRenderer {
}
}
boolean doSystem = true; // checkDoSystem(vs, src);
boolean doDefinition = checkDoDefinition(vs.getExpansion().getContains());
if (doSystem && allFromOneSystem(vs)) {
doSystem = false;
XhtmlNode p = x.para();
p.tx("All codes in this table are from the system ");
allCS = getContext().getWorker().fetchCodeSystem(vs.getExpansion().getContains().get(0).getSystem());
String ref = null;
if (allCS != null)
ref = getCsRef(allCS);
if (ref == null)
p.code(vs.getExpansion().getContains().get(0).getSystem());
else
p.ah(context.fixReference(ref)).code(vs.getExpansion().getContains().get(0).getSystem());
}
XhtmlNode t = x.table( "codes");
XhtmlNode tr = t.tr();
if (doLevel)
tr.td().b().tx("Level");
tr.td().attribute("style", "white-space:nowrap").b().tx("Code");
if (doSystem)
tr.td().b().tx("System");
tr.td().b().tx("System");
XhtmlNode tdDisp = tr.td();
tdDisp.b().tx("Display");
boolean doDesignations = false;
for (ValueSetExpansionContainsComponent c : vs.getExpansion().getContains()) {
scanForDesignations(c, langs, designations);
}
scanForProperties(vs.getExpansion(), langs, properties);
if (doDefinition) {
tr.td().b().tx("Definition");
doDesignations = false;
for (String n : Utilities.sorted(properties.keySet())) {
tr.td().b().ah(properties.get(n)).addText(n);
}
} else {
for (String n : Utilities.sorted(properties.keySet())) {
tr.td().b().ah(properties.get(n)).addText(n);
}
// if we're not doing definitions and we don't have too many languages, we'll do them in line
doDesignations = langs.size() + designations.size() < MAX_DESIGNATIONS_IN_LINE;
doDesignations = langs.size() + properties.size() + designations.size() < MAX_DESIGNATIONS_IN_LINE;
if (doDesignations) {
if (vs.hasLanguage()) {
@ -249,7 +245,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
addMapHeaders(tr, maps);
for (ValueSetExpansionContainsComponent c : vs.getExpansion().getContains()) {
addExpansionRowToTable(t, c, 1, doLevel, doSystem, doDefinition, maps, allCS, langs, designations, doDesignations);
addExpansionRowToTable(t, c, 1, doLevel, true, doDefinition, maps, allCS, langs, designations, doDesignations, properties);
}
// now, build observed languages
@ -280,6 +276,30 @@ public class ValueSetRenderer extends TerminologyRenderer {
return hasExtensions;
}
private void scanForProperties(ValueSetExpansionComponent exp, List<String> langs, Map<String, String> properties) {
properties.clear();
for (ValueSetExpansionPropertyComponent pp : exp.getProperty()) {
if (pp.hasCode() && pp.hasUri() && anyActualproperties(exp.getContains(), pp.getCode())) {
properties.put(pp.getCode(), pp.getUri());
}
}
}
private boolean anyActualproperties(List<ValueSetExpansionContainsComponent> contains, String pp) {
for (ValueSetExpansionContainsComponent c : contains) {
for (ConceptPropertyComponent cp : c.getProperty()) {
if (pp.equals(cp.getCode())) {
return true;
}
}
if (anyActualproperties(c.getContains(), pp)) {
return true;
}
}
return false;
}
private void generateContentModeNotices(XhtmlNode x, ValueSetExpansionComponent expansion) {
generateContentModeNotice(x, expansion, "example", "Expansion based on example code system");
generateContentModeNotice(x, expansion, "fragment", "Expansion based on code system fragment");
@ -715,7 +735,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
}
}
private void addExpansionRowToTable(XhtmlNode t, ValueSetExpansionContainsComponent c, int i, boolean doLevel, boolean doSystem, boolean doDefinition, List<UsedConceptMap> maps, CodeSystem allCS, List<String> langs, Map<String, String> designations, boolean doDesignations) {
private void addExpansionRowToTable(XhtmlNode t, ValueSetExpansionContainsComponent c, int i, boolean doLevel, boolean doSystem, boolean doDefinition, List<UsedConceptMap> maps, CodeSystem allCS, List<String> langs, Map<String, String> designations, boolean doDesignations, Map<String, String> properties) {
XhtmlNode tr = t.tr();
XhtmlNode td = tr.td();
@ -745,6 +765,13 @@ public class ValueSetRenderer extends TerminologyRenderer {
if (cs != null)
td.addText(CodeSystemUtilities.getCodeDefinition(cs, c.getCode()));
}
for (String n : Utilities.sorted(properties.keySet())) {
td = tr.td();
String ps = getPropertyValue(c, n);
if (!Utilities.noString(ps)) {
td.addText(ps);
}
}
for (UsedConceptMap m : maps) {
td = tr.td();
List<TargetElementComponentWrapper> mappings = findMappingsForCode(c.getCode(), m.getMap());
@ -765,7 +792,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
addLangaugesToRow(c, langs, tr);
}
for (ValueSetExpansionContainsComponent cc : c.getContains()) {
addExpansionRowToTable(t, cc, i+1, doLevel, doSystem, doDefinition, maps, allCS, langs, designations, doDesignations);
addExpansionRowToTable(t, cc, i+1, doLevel, doSystem, doDefinition, maps, allCS, langs, designations, doDesignations, properties);
}
}
@ -773,6 +800,15 @@ public class ValueSetRenderer extends TerminologyRenderer {
private String getPropertyValue(ValueSetExpansionContainsComponent c, String n) {
for (ConceptPropertyComponent cp : c.getProperty()) {
if (n.equals(cp.getCode())) {
return cp.getValue().primitiveValue();
}
}
return null;
}
private boolean checkSystemMatches(String system, ValueSetExpansionContainsComponent cc) {
if (!system.equals(cc.getSystem()))
return false;

View File

@ -241,11 +241,33 @@ public class CodeSystemUtilities {
}
}
public static boolean isInactive(CodeSystem cs, ConceptDefinitionComponent def, boolean ignoreStatus) {
try {
for (ConceptPropertyComponent p : def.getProperty()) {
if (!ignoreStatus) {
if ("status".equals(p.getCode()) && p.hasValue() && p.hasValueCodeType() && "inactive".equals(p.getValueCodeType().getCode()))
return true;
}
// legacy
if ("inactive".equals(p.getCode()) && p.hasValue() && p.getValue() instanceof BooleanType)
return ((BooleanType) p.getValue()).getValue();
}
return false;
} catch (FHIRException e) {
return false;
}
}
public static void setDeprecated(CodeSystem cs, ConceptDefinitionComponent concept, DateTimeType date) throws FHIRFormatError {
setStatus(cs, concept, ConceptStatus.Deprecated);
defineDeprecatedProperty(cs);
concept.addProperty().setCode("deprecationDate").setValue(date);
}
public static void setDeprecated(CodeSystem cs, ConceptDefinitionComponent concept) throws FHIRFormatError {
setStatus(cs, concept, ConceptStatus.Deprecated);
}
public static boolean isInactive(CodeSystem cs, ConceptDefinitionComponent def) throws FHIRException {
for (ConceptPropertyComponent p : def.getProperty()) {

View File

@ -108,6 +108,7 @@ import org.hl7.fhir.r5.model.ValueSet.ValueSetComposeComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionPropertyComponent;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.utilities.Utilities;
@ -207,7 +208,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
}
private ValueSetExpansionContainsComponent addCode(String system, String code, String display, ValueSetExpansionContainsComponent parent, List<ConceptDefinitionDesignationComponent> designations, Parameters expParams,
boolean isAbstract, boolean inactive, List<ValueSet> filters, boolean noInactive) {
boolean isAbstract, boolean inactive, List<ValueSet> filters, boolean noInactive, boolean deprecated, List<ValueSetExpansionPropertyComponent> vsProp) {
if (filters != null && !filters.isEmpty() && !filterContainsCode(filters, system, code))
return null;
@ -222,6 +223,9 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
n.setAbstract(true);
if (inactive)
n.setInactive(true);
if (deprecated) {
ValueSetUtilities.setDeprecated(vsProp, n);
}
if (expParams.getParameterBool("includeDesignations") && designations != null) {
for (ConceptDefinitionDesignationComponent t : designations) {
@ -285,12 +289,12 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
return null;
}
private void addCodeAndDescendents(ValueSetExpansionContainsComponent focus, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters, boolean noInactive) throws FHIRException {
private void addCodeAndDescendents(ValueSetExpansionContainsComponent focus, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps) throws FHIRException {
focus.checkNoModifiers("Expansion.contains", "expanding");
ValueSetExpansionContainsComponent np = addCode(focus.getSystem(), focus.getCode(), focus.getDisplay(), parent,
convert(focus.getDesignation()), expParams, focus.getAbstract(), focus.getInactive(), filters, noInactive);
convert(focus.getDesignation()), expParams, focus.getAbstract(), focus.getInactive(), filters, noInactive, false, vsProps);
for (ValueSetExpansionContainsComponent c : focus.getContains())
addCodeAndDescendents(focus, np, expParams, filters, noInactive);
addCodeAndDescendents(focus, np, expParams, filters, noInactive, vsProps);
}
private List<ConceptDefinitionDesignationComponent> convert(List<ConceptReferenceDesignationComponent> designations) {
@ -305,41 +309,31 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
return list;
}
private void addCodeAndDescendents(CodeSystem cs, String system, ConceptDefinitionComponent def, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters, ConceptDefinitionComponent exclusion, IConceptFilter filterFunc, boolean noInactive) throws FHIRException {
private void addCodeAndDescendents(CodeSystem cs, String system, ConceptDefinitionComponent def, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters, ConceptDefinitionComponent exclusion, IConceptFilter filterFunc, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps) throws FHIRException {
def.checkNoModifiers("Code in Code System", "expanding");
if (exclusion != null) {
if (exclusion.getCode().equals(def.getCode()))
return; // excluded.
}
if (!CodeSystemUtilities.isDeprecated(cs, def, false)) {
ValueSetExpansionContainsComponent np = null;
boolean abs = CodeSystemUtilities.isNotSelectable(cs, def);
boolean inc = CodeSystemUtilities.isInactive(cs, def);
if ((includeAbstract || !abs) && filterFunc.includeConcept(cs, def)) {
np = addCode(system, def.getCode(), def.getDisplay(), parent, def.getDesignation(), expParams, abs, inc, filters, noInactive);
}
for (ConceptDefinitionComponent c : def.getConcept()) {
addCodeAndDescendents(cs, system, c, np, expParams, filters, exclusion, filterFunc, noInactive);
}
if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) {
List<ConceptDefinitionComponent> children = (List<ConceptDefinitionComponent>) def.getUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK);
for (ConceptDefinitionComponent c : children)
addCodeAndDescendents(cs, system, c, np, expParams, filters, exclusion, filterFunc, noInactive);
}
} else {
for (ConceptDefinitionComponent c : def.getConcept()) {
addCodeAndDescendents(cs, system, c, null, expParams, filters, exclusion, filterFunc, noInactive);
}
if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) {
List<ConceptDefinitionComponent> children = (List<ConceptDefinitionComponent>) def.getUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK);
for (ConceptDefinitionComponent c : children)
addCodeAndDescendents(cs, system, c, null, expParams, filters, exclusion, filterFunc, noInactive);
}
ValueSetExpansionContainsComponent np = null;
boolean abs = CodeSystemUtilities.isNotSelectable(cs, def);
boolean inc = CodeSystemUtilities.isInactive(cs, def);
boolean dep = CodeSystemUtilities.isDeprecated(cs, def, false);
if ((includeAbstract || !abs) && filterFunc.includeConcept(cs, def)) {
np = addCode(system, def.getCode(), def.getDisplay(), parent, def.getDesignation(), expParams, abs, inc, filters, noInactive, dep, vsProps);
}
for (ConceptDefinitionComponent c : def.getConcept()) {
addCodeAndDescendents(cs, system, c, np, expParams, filters, exclusion, filterFunc, noInactive, vsProps);
}
if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) {
List<ConceptDefinitionComponent> children = (List<ConceptDefinitionComponent>) def.getUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK);
for (ConceptDefinitionComponent c : children)
addCodeAndDescendents(cs, system, c, np, expParams, filters, exclusion, filterFunc, noInactive, vsProps);
}
}
private void addCodes(ValueSetExpansionComponent expand, List<ValueSetExpansionParameterComponent> params, Parameters expParams, List<ValueSet> filters, boolean noInactive) throws ETooCostly, FHIRException {
private void addCodes(ValueSetExpansionComponent expand, List<ValueSetExpansionParameterComponent> params, Parameters expParams, List<ValueSet> filters, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps) throws ETooCostly, FHIRException {
if (expand != null) {
if (expand.getContains().size() > maxExpansionSize)
throw failCostly("Too many codes to display (>" + Integer.toString(expand.getContains().size()) + ")");
@ -348,7 +342,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
params.add(p);
}
copyImportContains(expand.getContains(), null, expParams, filters, noInactive);
copyImportContains(expand.getContains(), null, expParams, filters, noInactive, vsProps);
}
}
@ -578,11 +572,11 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
}
}
private void copyImportContains(List<ValueSetExpansionContainsComponent> list, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filter, boolean noInactive) throws FHIRException {
private void copyImportContains(List<ValueSetExpansionContainsComponent> list, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filter, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps) throws FHIRException {
for (ValueSetExpansionContainsComponent c : list) {
c.checkNoModifiers("Imported Expansion in Code System", "expanding");
ValueSetExpansionContainsComponent np = addCode(c.getSystem(), c.getCode(), c.getDisplay(), parent, null, expParams, c.getAbstract(), c.getInactive(), filter, noInactive);
copyImportContains(c.getContains(), np, expParams, filter, noInactive);
ValueSetExpansionContainsComponent np = addCode(c.getSystem(), c.getCode(), c.getDisplay(), parent, null, expParams, c.getAbstract(), c.getInactive(), filter, noInactive, false, vsProps);
copyImportContains(c.getContains(), np, expParams, filter, noInactive, vsProps);
}
}
@ -599,18 +593,18 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
ValueSet base = imports.get(0);
imports.remove(0);
base.checkNoModifiers("Imported ValueSet", "expanding");
copyImportContains(base.getExpansion().getContains(), null, expParams, imports, noInactive);
copyImportContains(base.getExpansion().getContains(), null, expParams, imports, noInactive, base.getExpansion().getProperty());
} else {
CodeSystem cs = context.fetchCodeSystem(inc.getSystem());
if (isServerSide(inc.getSystem()) || (cs == null || (cs.getContent() != CodeSystemContentMode.COMPLETE && cs.getContent() != CodeSystemContentMode.FRAGMENT))) {
doServerIncludeCodes(inc, heirarchical, exp, imports, expParams, extensions, noInactive);
doServerIncludeCodes(inc, heirarchical, exp, imports, expParams, extensions, noInactive, valueSet.getExpansion().getProperty());
} else {
doInternalIncludeCodes(inc, exp, expParams, imports, cs, noInactive);
}
}
}
private void doServerIncludeCodes(ConceptSetComponent inc, boolean heirarchical, ValueSetExpansionComponent exp, List<ValueSet> imports, Parameters expParams, List<Extension> extensions, boolean noInactive) throws FHIRException {
private void doServerIncludeCodes(ConceptSetComponent inc, boolean heirarchical, ValueSetExpansionComponent exp, List<ValueSet> imports, Parameters expParams, List<Extension> extensions, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps) throws FHIRException {
ValueSetExpansionOutcome vso = context.expandVS(inc, heirarchical, noInactive);
if (vso.getError() != null) {
throw failTSE("Unable to expand imported value set: " + vso.getError());
@ -634,7 +628,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
}
}
for (ValueSetExpansionContainsComponent cc : vs.getExpansion().getContains()) {
addCodeAndDescendents(cc, null, expParams, imports, noInactive);
addCodeAndDescendents(cc, null, expParams, imports, noInactive, vsProps);
}
}
@ -664,7 +658,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
if (inc.getConcept().size() == 0 && inc.getFilter().size() == 0) {
// special case - add all the code system
for (ConceptDefinitionComponent def : cs.getConcept()) {
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter(), noInactive, exp.getProperty());
}
if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
addFragmentWarning(exp, cs);
@ -693,7 +687,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
} else {
inactive = CodeSystemUtilities.isInactive(cs, def);
}
addCode(inc.getSystem(), c.getCode(), !Utilities.noString(c.getDisplay()) ? c.getDisplay() : def == null ? null : def.getDisplay(), null, convertDesignations(c.getDesignation()), expParams, false, inactive, imports, noInactive);
addCode(inc.getSystem(), c.getCode(), !Utilities.noString(c.getDisplay()) ? c.getDisplay() : def == null ? null : def.getDisplay(), null, convertDesignations(c.getDesignation()), expParams, false, inactive, imports, noInactive, false, exp.getProperty());
}
}
if (inc.getFilter().size() > 1) {
@ -710,14 +704,14 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
if (def == null)
throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter(), noInactive, exp.getProperty());
} else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.ISNOTA) {
// special: all codes in the target code system that are not under the value
ConceptDefinitionComponent defEx = getConceptForCode(cs.getConcept(), fc.getValue());
if (defEx == null)
throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
for (ConceptDefinitionComponent def : cs.getConcept()) {
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, defEx, new AllConceptsFilter(), noInactive);
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, defEx, new AllConceptsFilter(), noInactive, exp.getProperty());
}
} else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.DESCENDENTOF) {
// special: all codes in the target code system under the value
@ -725,11 +719,11 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
if (def == null)
throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
for (ConceptDefinitionComponent c : def.getConcept())
addCodeAndDescendents(cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
addCodeAndDescendents(cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter(), noInactive, exp.getProperty());
if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) {
List<ConceptDefinitionComponent> children = (List<ConceptDefinitionComponent>) def.getUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK);
for (ConceptDefinitionComponent c : children)
addCodeAndDescendents(cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
addCodeAndDescendents(cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter(), noInactive, exp.getProperty());
}
} else if ("display".equals(fc.getProperty()) && fc.getOp() == FilterOperator.EQUAL) {
@ -740,13 +734,13 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
if (isNotBlank(def.getDisplay()) && isNotBlank(fc.getValue())) {
if (def.getDisplay().contains(fc.getValue())) {
addCode(inc.getSystem(), def.getCode(), def.getDisplay(), null, def.getDesignation(), expParams, CodeSystemUtilities.isNotSelectable(cs, def), CodeSystemUtilities.isInactive(cs, def),
imports, noInactive);
imports, noInactive, false, exp.getProperty());
}
}
}
} else if (isDefinedProperty(cs, fc.getProperty())) {
for (ConceptDefinitionComponent def : cs.getConcept()) {
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new PropertyFilter(fc, getPropertyDefinition(cs, fc.getProperty())), noInactive);
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new PropertyFilter(fc, getPropertyDefinition(cs, fc.getProperty())), noInactive, exp.getProperty());
}
} else {
throw fail("Search by property[" + fc.getProperty() + "] and op[" + fc.getOp() + "] is not supported yet");

View File

@ -1,5 +1,7 @@
package org.hl7.fhir.r5.terminologies;
import java.util.List;
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
@ -31,16 +33,24 @@ package org.hl7.fhir.r5.terminologies;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.model.BooleanType;
import org.hl7.fhir.r5.model.CanonicalType;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.DateTimeType;
import org.hl7.fhir.r5.model.Enumerations.FilterOperator;
import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
import org.hl7.fhir.r5.model.Identifier;
import org.hl7.fhir.r5.model.Meta;
import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionPropertyComponent;
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities.ConceptStatus;
import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.utilities.StandardsStatus;
import org.hl7.fhir.utilities.Utilities;
@ -234,4 +244,15 @@ public class ValueSetUtilities {
return vs;
}
public static void setDeprecated(List<ValueSetExpansionPropertyComponent> vsProp, ValueSetExpansionContainsComponent n) {
n.addProperty().setCode("status").setValue(new CodeType("deprecated"));
for (ValueSetExpansionPropertyComponent o : vsProp) {
if ("status".equals(o.getCode())) {
return;
}
}
vsProp.add(new ValueSetExpansionPropertyComponent().setCode("status").setUri("http://hl7.org/fhir/concept-properties#status"));
}
}