Fix expansion related bugs and adjust tests accordingly
This commit is contained in:
parent
29dbcbfb63
commit
bf57789467
|
@ -866,16 +866,15 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
if (noTerminologyServer) {
|
||||
return new ValueSetExpansionOutcome(formatMessage(I18nConstants.ERROR_EXPANDING_VALUESET_RUNNING_WITHOUT_TERMINOLOGY_SERVICES), TerminologyServiceErrorClass.NOSERVICE, false);
|
||||
}
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("_limit", Integer.toString(expandCodesLimit ));
|
||||
params.put("_incomplete", "true");
|
||||
p.addParameter("count", expandCodesLimit);
|
||||
p.addParameter("offset", 0);
|
||||
txLog("$expand on "+txCache.summary(vs)+" on "+tc.getAddress());
|
||||
if (addDependentResources(tc, p, vs)) {
|
||||
p.addParameter().setName("cache-id").setValue(new IdType(terminologyClientManager.getCacheId()));
|
||||
}
|
||||
|
||||
try {
|
||||
ValueSet result = tc.getClient().expandValueset(vs, p, params);
|
||||
ValueSet result = tc.getClient().expandValueset(vs, p, null);
|
||||
res = new ValueSetExpansionOutcome(result).setTxLink(txLog.getLastId());
|
||||
} catch (Exception e) {
|
||||
res = new ValueSetExpansionOutcome(e.getMessage() == null ? e.getClass().getName() : e.getMessage(), TerminologyServiceErrorClass.UNKNOWN, true);
|
||||
|
@ -904,6 +903,10 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
|
||||
public ValueSetExpansionOutcome expandVS(ValueSet vs, boolean cacheOk, boolean hierarchical, boolean incompleteOk, Parameters pIn) {
|
||||
return expandVS(vs, cacheOk, hierarchical, incompleteOk, pIn, false);
|
||||
}
|
||||
|
||||
public ValueSetExpansionOutcome expandVS(ValueSet vs, boolean cacheOk, boolean hierarchical, boolean incompleteOk, Parameters pIn, boolean noLimits) {
|
||||
if (pIn == null) {
|
||||
throw new Error(formatMessage(I18nConstants.NO_PARAMETERS_PROVIDED_TO_EXPANDVS));
|
||||
}
|
||||
|
@ -934,7 +937,11 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!noLimits) {
|
||||
p.addParameter("count", expandCodesLimit);
|
||||
p.addParameter("offset", 0);
|
||||
}
|
||||
p.setParameter("excludeNested", !hierarchical);
|
||||
if (incompleteOk) {
|
||||
p.setParameter("incomplete-ok", true);
|
||||
|
@ -973,15 +980,12 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
Set<String> systems = findRelevantSystems(vs);
|
||||
TerminologyClientContext tc = terminologyClientManager.chooseServer(systems, true);
|
||||
addDependentResources(tc, p, vs);
|
||||
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("_limit", Integer.toString(expandCodesLimit ));
|
||||
params.put("_incomplete", "true");
|
||||
|
||||
|
||||
txLog("$expand on "+txCache.summary(vs)+" on "+tc.getAddress());
|
||||
|
||||
try {
|
||||
ValueSet result = tc.getClient().expandValueset(vs, p, params);
|
||||
ValueSet result = tc.getClient().expandValueset(vs, p, null);
|
||||
if (result != null) {
|
||||
if (!result.hasUrl()) {
|
||||
result.setUrl(vs.getUrl());
|
||||
|
|
|
@ -1729,6 +1729,11 @@ public String toString() {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Parameters addParameter(String name, int i) {
|
||||
addParameter().setName(name).setValue(new IntegerType(i));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Parameters addParameter(String name, String s) {
|
||||
if (s != null)
|
||||
addParameter().setName(name).setValue(new StringType(s));
|
||||
|
|
|
@ -7,8 +7,10 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
|
@ -191,22 +193,35 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
generateVersionNotice(x, vs.getExpansion(), vs);
|
||||
|
||||
if (ToolingExtensions.hasExtension(vs.getExpansion(), ToolingExtensions.EXT_EXP_TOOCOSTLY)) {
|
||||
List<Extension> exl = vs.getExpansion().getExtensionsByUrl(ToolingExtensions.EXT_EXP_TOOCOSTLY);
|
||||
boolean other = false;
|
||||
for (Extension ex : exl) {
|
||||
if (ex.getValue() instanceof BooleanType) {
|
||||
x.para().style("border: maroon 1px solid; background-color: #FFCCCC; font-weight: bold; padding: 8px").addText(vs.getExpansion().getContains().isEmpty() ? getContext().getTooCostlyNoteEmpty() : getContext().getTooCostlyNoteNotEmpty());
|
||||
} else if (!other) {
|
||||
x.para().style("border: maroon 1px solid; background-color: #FFCCCC; font-weight: bold; padding: 8px").addText(vs.getExpansion().getContains().isEmpty() ? getContext().getTooCostlyNoteEmptyDependent() : getContext().getTooCostlyNoteNotEmptyDependent());
|
||||
other = true;
|
||||
}
|
||||
// List<Extension> exl = vs.getExpansion().getExtensionsByUrl(ToolingExtensions.EXT_EXP_TOOCOSTLY);
|
||||
// boolean other = false;
|
||||
// for (Extension ex : exl) {
|
||||
// if (ex.getValue() instanceof BooleanType) {
|
||||
// x.para().style("border: maroon 1px solid; background-color: #FFCCCC; font-weight: bold; padding: 8px").addText(vs.getExpansion().getContains().isEmpty() ? getContext().getTooCostlyNoteEmpty() : getContext().getTooCostlyNoteNotEmpty());
|
||||
// } else if (!other) {
|
||||
// x.para().style("border: maroon 1px solid; background-color: #FFCCCC; font-weight: bold; padding: 8px").addText(vs.getExpansion().getContains().isEmpty() ? getContext().getTooCostlyNoteEmptyDependent() : getContext().getTooCostlyNoteNotEmptyDependent());
|
||||
// other = true;
|
||||
// }
|
||||
// }
|
||||
String msg = null;
|
||||
if (vs.getExpansion().getContains().isEmpty()) {
|
||||
msg = "This value set cannot be expanded because of the way it is defined - it has an infinite number of members"; // not sure that's true?
|
||||
} else {
|
||||
msg = "This value set cannot be fully expanded, but a selection ("+countMembership(vs)+" codes) of the whole set of codes is shown here";
|
||||
}
|
||||
x.para().style("border: maroon 1px solid; background-color: #FFCCCC; font-weight: bold; padding: 8px").addText(msg);
|
||||
} else {
|
||||
Integer count = countMembership(vs);
|
||||
if (count == null)
|
||||
x.para().tx("This value set does not contain a fixed number of concepts");
|
||||
else
|
||||
x.para().tx("This value set contains "+(hasFragment ? "at least " : "")+count.toString()+" concepts");
|
||||
int count = conceptCount(vs.getExpansion().getContains());
|
||||
if (vs.getExpansion().hasTotal()) {
|
||||
if (count != vs.getExpansion().getTotal()) {
|
||||
x.para().style("border: maroon 1px solid; background-color: #FFCCCC; font-weight: bold; padding: 8px")
|
||||
.addText("This value set has "+(hasFragment ? "at least " : "")+vs.getExpansion().getTotal()+" codes in it. In order to keep the publication size manageable, only a selection ("+count+" codes) of the whole set of codes is shown");
|
||||
} else {
|
||||
x.para().tx("This value set contains "+(hasFragment ? "at least " : "")+vs.getExpansion().getTotal()+" concepts");
|
||||
}
|
||||
} else {
|
||||
x.para().tx("This value set expansion contains "+count+" concepts");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -403,7 +418,6 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
private Integer countMembership(ValueSet vs) {
|
||||
int count = 0;
|
||||
if (vs.hasExpansion())
|
||||
|
@ -457,9 +471,11 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
@SuppressWarnings("rawtypes")
|
||||
private void generateVersionNotice(XhtmlNode x, ValueSetExpansionComponent expansion, Resource vs) {
|
||||
Multimap<String, String> versions = HashMultimap.create();
|
||||
Set<String> vlist = new HashSet<>();
|
||||
for (ValueSetExpansionParameterComponent p : expansion.getParameter()) {
|
||||
if (p.getName().startsWith("used-") || p.getName().equals("version")) {
|
||||
if ((p.getName().startsWith("used-") || p.getName().equals("version")) && !vlist.contains(p.getValue().primitiveValue())) {
|
||||
String name = p.getName().equals("version") ? "system" : p.getName().substring(5);
|
||||
vlist.add(p.getValue().primitiveValue());
|
||||
String[] parts = ((PrimitiveType) p.getValue()).asStringValue().split("\\|");
|
||||
if (parts.length == 2 && !Utilities.noString(parts[0]))
|
||||
versions.put(name+"|"+parts[0], parts[1]);
|
||||
|
|
|
@ -60,6 +60,7 @@ import org.hl7.fhir.r5.model.DataType;
|
|||
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||
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.ValueSetExpansionPropertyComponent;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities.ConceptDefinitionComponentSorter;
|
||||
|
@ -456,5 +457,29 @@ public class ValueSetUtilities extends TerminologyUtilities {
|
|||
}
|
||||
return systems;
|
||||
}
|
||||
|
||||
|
||||
private static int conceptCount(List<ValueSetExpansionContainsComponent> list) {
|
||||
int count = 0;
|
||||
for (ValueSetExpansionContainsComponent c : list) {
|
||||
if (!c.getAbstract())
|
||||
count++;
|
||||
count = count + conceptCount(c.getContains());
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isIncompleteExpansion(ValueSet valueSet) {
|
||||
if (valueSet.hasExpansion()) {
|
||||
ValueSetExpansionComponent exp = valueSet.getExpansion();
|
||||
if (exp.hasTotal()) {
|
||||
if (exp.getTotal() != conceptCount(exp.getContains())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -35,6 +35,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011+, HL7, Inc
|
||||
|
@ -186,7 +187,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
|
||||
private ValueSetExpansionContainsComponent addCode(WorkingContext wc, String system, String code, String display, String dispLang, ValueSetExpansionContainsComponent parent, List<ConceptDefinitionDesignationComponent> designations, Parameters expParams,
|
||||
boolean isAbstract, boolean inactive, List<ValueSet> filters, boolean noInactive, boolean deprecated, List<ValueSetExpansionPropertyComponent> vsProp,
|
||||
List<ConceptPropertyComponent> csProps, CodeSystem cs, List<org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent> expProps, List<Extension> csExtList, List<Extension> vsExtList, ValueSetExpansionComponent exp) throws ETooCostly {
|
||||
List<ConceptPropertyComponent> csProps, CodeSystem cs, List<org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent> expProps, List<Extension> csExtList, List<Extension> vsExtList, ValueSetExpansionComponent exp, boolean countToTotal) throws ETooCostly {
|
||||
opContext.deadCheck();
|
||||
|
||||
if (filters != null && !filters.isEmpty() && !filterContainsCode(filters, system, code, exp))
|
||||
|
@ -323,14 +324,16 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
} else {
|
||||
wc.getCodes().add(n);
|
||||
wc.getMap().put(s, n);
|
||||
wc.incTotal();
|
||||
if (wc == dwc && wc.getTotal() > maxExpansionSize) {
|
||||
if (wc.getOffset()+wc.getCount() > 0 && wc.getTotal() > wc.getOffset()+wc.getCount()) {
|
||||
wc.setTotal(-1);
|
||||
throw new EFinished();
|
||||
}
|
||||
throw failCostly(context.formatMessage(I18nConstants.VALUESET_TOO_COSTLY, focus.getUrl(), ">" + Integer.toString(maxExpansionSize)));
|
||||
if (countToTotal) {
|
||||
wc.incTotal();
|
||||
}
|
||||
// if (wc == dwc && wc.getTotal() > maxExpansionSize) {
|
||||
// if (wc.getOffset()+wc.getCount() > 0 && wc.getTotal() > wc.getOffset()+wc.getCount()) {
|
||||
// wc.setTotal(-1);
|
||||
// throw new EFinished();
|
||||
// }
|
||||
// throw failCostly(context.formatMessage(I18nConstants.VALUESET_TOO_COSTLY, focus.getUrl(), ">" + Integer.toString(maxExpansionSize)));
|
||||
// }
|
||||
}
|
||||
if (wc.isCanBeHeirarchy() && parent != null) {
|
||||
parent.getContains().add(n);
|
||||
|
@ -443,19 +446,19 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void addCodeAndDescendents(WorkingContext wc, ValueSetExpansionContainsComponent focus, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps, ValueSet vsSrc, ValueSetExpansionComponent exp) throws FHIRException, ETooCostly {
|
||||
private void addCodeAndDescendents(WorkingContext wc, ValueSetExpansionContainsComponent focus, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps, ValueSet vsSrc, ValueSetExpansionComponent exp, boolean countToTotal) throws FHIRException, ETooCostly {
|
||||
opContext.deadCheck();
|
||||
focus.checkNoModifiers("Expansion.contains", "expanding");
|
||||
ValueSetExpansionContainsComponent np = null;
|
||||
for (String code : getCodesForConcept(focus, expParams)) {
|
||||
ValueSetExpansionContainsComponent t = addCode(wc, focus.getSystem(), code, focus.getDisplay(), vsSrc.getLanguage(), parent,
|
||||
convert(focus.getDesignation()), expParams, focus.getAbstract(), focus.getInactive(), filters, noInactive, false, vsProps, makeCSProps(focus.getExtensionString(ToolingExtensions.EXT_DEFINITION), null), null, focus.getProperty(), null, focus.getExtension(), exp);
|
||||
convert(focus.getDesignation()), expParams, focus.getAbstract(), focus.getInactive(), filters, noInactive, false, vsProps, makeCSProps(focus.getExtensionString(ToolingExtensions.EXT_DEFINITION), null), null, focus.getProperty(), null, focus.getExtension(), exp, countToTotal);
|
||||
if (np == null) {
|
||||
np = t;
|
||||
}
|
||||
}
|
||||
for (ValueSetExpansionContainsComponent c : focus.getContains())
|
||||
addCodeAndDescendents(wc, c, np, expParams, filters, noInactive, vsProps, vsSrc, exp);
|
||||
addCodeAndDescendents(wc, c, np, expParams, filters, noInactive, vsProps, vsSrc, exp, countToTotal);
|
||||
}
|
||||
|
||||
private List<ConceptPropertyComponent> makeCSProps(String definition, List<ConceptPropertyComponent> list) {
|
||||
|
@ -506,7 +509,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
boolean dep = CodeSystemUtilities.isDeprecated(cs, def, false);
|
||||
if ((includeAbstract || !abs) && filterFunc.includeConcept(cs, def) && passesOtherFilters(otherFilters, cs, def.getCode())) {
|
||||
for (String code : getCodesForConcept(def, expParams)) {
|
||||
ValueSetExpansionContainsComponent t = addCode(wc, system, code, def.getDisplay(), cs.getLanguage(), parent, def.getDesignation(), expParams, abs, inc, filters, noInactive, dep, vsProps, makeCSProps(def.getDefinition(), def.getProperty()), cs, null, def.getExtension(), null, exp);
|
||||
ValueSetExpansionContainsComponent t = addCode(wc, system, code, def.getDisplay(), cs.getLanguage(), parent, def.getDesignation(), expParams, abs, inc, filters, noInactive, dep, vsProps, makeCSProps(def.getDefinition(), def.getProperty()), cs, null, def.getExtension(), null, exp, true);
|
||||
if (np == null) {
|
||||
np = t;
|
||||
}
|
||||
|
@ -579,7 +582,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
if (!existsInParams(params, p.getName(), p.getValue()))
|
||||
params.add(p);
|
||||
}
|
||||
|
||||
|
||||
copyImportContains(expand.getContains(), null, expParams, filters, noInactive, vsProps, vsSrc, exp);
|
||||
}
|
||||
}
|
||||
|
@ -707,17 +710,17 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
if ("offset".equals(name) && value instanceof IntegerType) {
|
||||
focus.getExpansion().getParameter().removeIf(p -> p.getName().equals(name));
|
||||
focus.getExpansion().addParameter().setName(name).setValue(value);
|
||||
dwc.setOffset(((IntegerType) value).getValue());
|
||||
if (dwc.getOffset() < 0) {
|
||||
dwc.setOffset(0);
|
||||
dwc.setOffsetParam(((IntegerType) value).getValue());
|
||||
if (dwc.getOffsetParam() < 0) {
|
||||
dwc.setOffsetParam(0);
|
||||
}
|
||||
}
|
||||
if ("count".equals(name)) {
|
||||
focus.getExpansion().getParameter().removeIf(p -> p.getName().equals(name));
|
||||
focus.getExpansion().addParameter().setName(name).setValue(value);
|
||||
dwc.setCount(((IntegerType) value).getValue());
|
||||
if (dwc.getCount() < 0) {
|
||||
dwc.setCount(0);
|
||||
dwc.setCountParam(((IntegerType) value).getValue());
|
||||
if (dwc.getCountParam() < 0) {
|
||||
dwc.setCountParam(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -757,7 +760,13 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
// nothing - we intended to trap this here
|
||||
}
|
||||
|
||||
if (dwc.isCanBeHeirarchy()) {
|
||||
if (dwc.getTotal() > maxExpansionSize && dwc.getOffsetParam() + dwc.getCountParam() == 0) {
|
||||
if (dwc.isNoTotal()) {
|
||||
throw failCostly(context.formatMessage(I18nConstants.VALUESET_TOO_COSTLY, focus.getVersionedUrl(), ">" + MessageFormat.format("{0,number,#}", maxExpansionSize)));
|
||||
} else {
|
||||
throw failCostly(context.formatMessage(I18nConstants.VALUESET_TOO_COSTLY_COUNT, focus.getVersionedUrl(), ">" + MessageFormat.format("{0,number,#}", maxExpansionSize), MessageFormat.format("{0,number,#}", dwc.getTotal())));
|
||||
}
|
||||
} else if (dwc.isCanBeHeirarchy() && (dwc.getCountParam() == 0) || dwc.getCountParam() > dwc.getCodes().size()) {
|
||||
for (ValueSetExpansionContainsComponent c : dwc.getRoots()) {
|
||||
focus.getExpansion().getContains().add(c);
|
||||
}
|
||||
|
@ -766,11 +775,11 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
int cc = 0;
|
||||
for (ValueSetExpansionContainsComponent c : dwc.getCodes()) {
|
||||
if (dwc.getMap().containsKey(key(c)) && (includeAbstract || !c.getAbstract())) { // we may have added abstract codes earlier while we still thought it might be heirarchical, but later we gave up, so now ignore them
|
||||
if (dwc.getOffset() == 0 || i >= dwc.getOffset()) {
|
||||
if (dwc.getOffsetParam() == 0 || i >= dwc.getOffsetParam()) {
|
||||
focus.getExpansion().getContains().add(c);
|
||||
c.getContains().clear(); // make sure any heirarchy is wiped
|
||||
cc++;
|
||||
if (cc == dwc.getCount()) {
|
||||
if (cc == dwc.getCountParam()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -779,10 +788,10 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
}
|
||||
}
|
||||
|
||||
if (dwc.hasOffset()) {
|
||||
focus.getExpansion().setOffset(dwc.getOffset());
|
||||
if (dwc.hasOffsetParam()) {
|
||||
focus.getExpansion().setOffset(dwc.getOffsetParam());
|
||||
}
|
||||
if (dwc.getTotal() >= 0) {
|
||||
if (!dwc.isNoTotal()) {
|
||||
focus.getExpansion().setTotal(dwc.getTotal());
|
||||
}
|
||||
if (!requiredSupplements.isEmpty()) {
|
||||
|
@ -826,7 +835,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
// Exclude comes first because we build up a map of things to exclude
|
||||
for (ConceptSetComponent inc : compose.getExclude())
|
||||
excludeCodes(dwc, inc, expParams, exp, valueSet);
|
||||
dwc.setCanBeHeirarchy(!expParams.getParameterBool("excludeNested") && dwc.getExcludeKeys().isEmpty() && dwc.getExcludeSystems().isEmpty() && dwc.getOffset()+dwc.getCount() == 0);
|
||||
dwc.setCanBeHeirarchy(!expParams.getParameterBool("excludeNested") && dwc.getExcludeKeys().isEmpty() && dwc.getExcludeSystems().isEmpty() && dwc.getOffsetParam() == 0);
|
||||
includeAbstract = !expParams.getParameterBool("excludeNotForUI");
|
||||
boolean first = true;
|
||||
for (ConceptSetComponent inc : compose.getInclude()) {
|
||||
|
@ -878,7 +887,8 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
if (!existsInParams(exp.getParameter(), "used-valueset", u))
|
||||
exp.getParameter().add(new ValueSetExpansionParameterComponent().setName("used-valueset").setValue(u));
|
||||
}
|
||||
for (Extension ex : vso.getValueset().getExpansion().getExtension()) {
|
||||
ValueSetExpansionComponent evs = vso.getValueset().getExpansion();
|
||||
for (Extension ex : evs.getExtension()) {
|
||||
if (ex.getUrl().equals(ToolingExtensions.EXT_EXP_TOOCOSTLY)) {
|
||||
if (ex.getValue() instanceof BooleanType) {
|
||||
exp.getExtension().add(new Extension(ToolingExtensions.EXT_EXP_TOOCOSTLY).setValue(new CanonicalType(value)));
|
||||
|
@ -887,12 +897,17 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
}
|
||||
}
|
||||
}
|
||||
for (ValueSetExpansionParameterComponent p : vso.getValueset().getExpansion().getParameter()) {
|
||||
if (evs.hasTotal()) {
|
||||
dwc.incTotal(evs.getTotal());
|
||||
} else {
|
||||
dwc.setNoTotal(true);
|
||||
}
|
||||
for (ValueSetExpansionParameterComponent p : evs.getParameter()) {
|
||||
if (!existsInParams(exp.getParameter(), p.getName(), p.getValue()))
|
||||
exp.getParameter().add(p);
|
||||
}
|
||||
if (isValueSetUnionImports(valueSet)) {
|
||||
copyExpansion(wc, vso.getValueset().getExpansion().getContains());
|
||||
copyExpansion(wc, evs.getContains());
|
||||
}
|
||||
wc.setCanBeHeirarchy(false); // if we're importing a value set, we have to be combining, so we won't try for a heirarchy
|
||||
return vso.getValueset();
|
||||
|
@ -976,7 +991,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
for (ValueSetExpansionContainsComponent c : list) {
|
||||
c.checkNoModifiers("Imported Expansion in Code System", "expanding");
|
||||
ValueSetExpansionContainsComponent np = addCode(dwc, c.getSystem(), c.getCode(), c.getDisplay(), vsSrc.getLanguage(), parent, null, expParams, c.getAbstract(), c.getInactive(),
|
||||
filter, noInactive, false, vsProps, makeCSProps(c.getExtensionString(ToolingExtensions.EXT_DEFINITION), null), null, c.getProperty(), null, c.getExtension(), exp);
|
||||
filter, noInactive, false, vsProps, makeCSProps(c.getExtensionString(ToolingExtensions.EXT_DEFINITION), null), null, c.getProperty(), null, c.getExtension(), exp, false);
|
||||
copyImportContains(c.getContains(), np, expParams, filter, noInactive, vsProps, vsSrc, exp);
|
||||
}
|
||||
}
|
||||
|
@ -1031,6 +1046,11 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
exp.getParameter().add(new ValueSetExpansionParameterComponent().setName("used-valueset").setValue(u));
|
||||
}
|
||||
}
|
||||
if (vs.getExpansion().hasTotal()) {
|
||||
dwc.incTotal(vs.getExpansion().getTotal());
|
||||
} else {
|
||||
dwc.setNoTotal(true);
|
||||
}
|
||||
for (ValueSetExpansionParameterComponent p : vso.getValueset().getExpansion().getParameter()) {
|
||||
if (!existsInParams(exp.getParameter(), p.getName(), p.getValue())) {
|
||||
exp.getParameter().add(p);
|
||||
|
@ -1044,7 +1064,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
}
|
||||
}
|
||||
for (ValueSetExpansionContainsComponent cc : vs.getExpansion().getContains()) {
|
||||
addCodeAndDescendents(dwc, cc, null, expParams, imports, noInactive, vsProps, vs, exp);
|
||||
addCodeAndDescendents(dwc, cc, null, expParams, imports, noInactive, vsProps, vs, exp, !vs.getExpansion().hasTotal());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1109,7 +1129,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
inactive = CodeSystemUtilities.isInactive(cs, def);
|
||||
isAbstract = CodeSystemUtilities.isNotSelectable(cs, def);
|
||||
addCode(dwc, inc.getSystem(), c.getCode(), !Utilities.noString(c.getDisplay()) ? c.getDisplay() : def.getDisplay(), c.hasDisplay() ? vsSrc.getLanguage() : cs.getLanguage(), null, mergeDesignations(def, convertDesignations(c.getDesignation())),
|
||||
expParams, isAbstract, inactive, imports, noInactive, false, exp.getProperty(), makeCSProps(def.getDefinition(), def.getProperty()), cs, null, def.getExtension(), c.getExtension(), exp);
|
||||
expParams, isAbstract, inactive, imports, noInactive, false, exp.getProperty(), makeCSProps(def.getDefinition(), def.getProperty()), cs, null, def.getExtension(), c.getExtension(), exp, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1193,7 +1213,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
excludeCode(wc, inc.getSystem(), code);
|
||||
} else {
|
||||
addCode(wc, inc.getSystem(), code, def.getDisplay(), cs.getLanguage(), null, def.getDesignation(), expParams, CodeSystemUtilities.isNotSelectable(cs, def), CodeSystemUtilities.isInactive(cs, def),
|
||||
imports, noInactive, false, exp.getProperty(), makeCSProps(def.getDefinition(), def.getProperty()), cs, null, def.getExtension(), null, exp);
|
||||
imports, noInactive, false, exp.getProperty(), makeCSProps(def.getDefinition(), def.getProperty()), cs, null, def.getExtension(), null, exp, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,10 @@ class WorkingContext {
|
|||
private Set<String> excludeSystems = new HashSet<String>();
|
||||
|
||||
private boolean canBeHeirarchy = true;
|
||||
private int offset;
|
||||
private boolean offs;
|
||||
private int count;
|
||||
private int total;
|
||||
private Integer offsetParam;
|
||||
private Integer countParam; // allowed count. Because of internal processing, we allow more
|
||||
private int total; // running count. This might be more than actually seen if we call out to an external server and only get the first 1000 codes
|
||||
private boolean noTotal; // we lost count of the correct total
|
||||
|
||||
public List<ValueSetExpansionContainsComponent> getCodes() {
|
||||
return codes;
|
||||
|
@ -51,37 +51,48 @@ class WorkingContext {
|
|||
this.canBeHeirarchy = canBeHeirarchy;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
public boolean hasOffsetParam() {
|
||||
return offsetParam != null;
|
||||
}
|
||||
|
||||
public void setOffset(int offset) {
|
||||
this.offs = true;
|
||||
this.offset = offset;
|
||||
public int getOffsetParam() {
|
||||
return offsetParam == null ? 0 : offsetParam;
|
||||
}
|
||||
|
||||
public boolean hasOffset() {
|
||||
return offs;
|
||||
public void setOffsetParam(int offsetParam) {
|
||||
this.offsetParam = offsetParam;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
public boolean hasCountParam() {
|
||||
return countParam != null;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
public int getCountParam() {
|
||||
return countParam == null ? 0 : countParam;
|
||||
}
|
||||
|
||||
public void setCountParam(int countParam) {
|
||||
this.countParam = countParam;
|
||||
}
|
||||
|
||||
public int getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(int total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public void incTotal() {
|
||||
total++;
|
||||
}
|
||||
|
||||
public void incTotal(int amount) {
|
||||
total += amount;
|
||||
}
|
||||
|
||||
public boolean isNoTotal() {
|
||||
return noTotal;
|
||||
}
|
||||
|
||||
public void setNoTotal(boolean noTotal) {
|
||||
this.noTotal = noTotal;
|
||||
}
|
||||
|
||||
}
|
|
@ -878,6 +878,7 @@ public class I18nConstants {
|
|||
public static final String UNKNOWN_CODESYSTEM = "UNKNOWN_CODESYSTEM";
|
||||
public static final String UNKNOWN_CODESYSTEM_VERSION = "UNKNOWN_CODESYSTEM_VERSION";
|
||||
public static final String VALUESET_TOO_COSTLY = "VALUESET_TOO_COSTLY";
|
||||
public static final String VALUESET_TOO_COSTLY_COUNT = "VALUESET_TOO_COSTLY_COUNT";
|
||||
public static final String VALUESET_TOO_COSTLY_TIME = "VALUESET_TOO_COSTLY_TIME";
|
||||
public static final String NO_VALID_DISPLAY_FOUND = "NO_VALID_DISPLAY_FOUND";
|
||||
public static final String SD_NO_CONTEXT_WHEN_NOT_EXTENSION = "SD_NO_CONTEXT_WHEN_NOT_EXTENSION";
|
||||
|
|
|
@ -933,8 +933,9 @@ SD_NO_TYPE_CODE_ON_CODE = Snapshot for {1} element {0} has type.code without a v
|
|||
UNKNOWN_CODESYSTEM = A definition for CodeSystem ''{0}'' could not be found, so the code cannot be validated
|
||||
UNKNOWN_CODESYSTEM_VERSION = A definition for CodeSystem ''{0}'' version ''{1}'' could not be found, so the code cannot be validated. Valid versions: {2}
|
||||
UNABLE_TO_INFER_CODESYSTEM = The System URI could not be determined for the code {0} in the ValueSet {1}
|
||||
VALUESET_TOO_COSTLY = The value set {0} has too many codes to display ({1})
|
||||
VALUESET_TOO_COSTLY_TIME = The value set {0} took too long to process (>{1}sec)
|
||||
VALUESET_TOO_COSTLY = The value set ''{0}'' expansion has too many codes to display ({1})
|
||||
VALUESET_TOO_COSTLY_COUNT = The value set ''{0}'' expansion has {2} codes, which is too many to display ({1})
|
||||
VALUESET_TOO_COSTLY_TIME = The value set ''{0}'' expansion took too long to process (>{1}sec)
|
||||
NO_VALID_DISPLAY_FOUND_one = No valid Display Names found for {1}#{2} in the language {4}
|
||||
NO_VALID_DISPLAY_FOUND_other = No valid Display Names found for {1}#{2} in the languages {4}
|
||||
SD_NO_CONTEXT_WHEN_NOT_EXTENSION = The type is {0} so an extension context should not be specified
|
||||
|
|
|
@ -164,7 +164,7 @@ public class TerminologyServiceTests {
|
|||
if (lang != null && !p.hasParameter("displayLanguage")) {
|
||||
p.addParameter("displayLanguage", new CodeType(lang));
|
||||
}
|
||||
ValueSetExpansionOutcome vse = engine.getContext().expandVS(vs, false, hierarchical, false, p);
|
||||
ValueSetExpansionOutcome vse = engine.getContext().expandVS(vs, false, hierarchical, false, p, true);
|
||||
if (resp.contains("\"ValueSet\"")) {
|
||||
if (vse.getValueset() == null) {
|
||||
Assertions.fail(vse.getError());
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -20,7 +20,7 @@
|
|||
<properties>
|
||||
<guava_version>32.0.1-jre</guava_version>
|
||||
<hapi_fhir_version>6.4.1</hapi_fhir_version>
|
||||
<validator_test_case_version>1.4.25</validator_test_case_version>
|
||||
<validator_test_case_version>1.4.26-SNAPSHOT</validator_test_case_version>
|
||||
<jackson_version>2.16.0</jackson_version>
|
||||
<junit_jupiter_version>5.9.2</junit_jupiter_version>
|
||||
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>
|
||||
|
|
Loading…
Reference in New Issue