Add terminology service tests
This commit is contained in:
parent
0bbff8d14d
commit
42a9e47379
|
@ -820,7 +820,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
return res;
|
||||
}
|
||||
}
|
||||
p.setParameter("includeDefinition", false);
|
||||
|
||||
p.setParameter("excludeNested", !hierarchical);
|
||||
if (incompleteOk) {
|
||||
p.setParameter("incomplete-ok", true);
|
||||
|
@ -872,7 +872,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
res = new ValueSetExpansionOutcome(result).setTxLink(txLog.getLastId());
|
||||
} catch (Exception e) {
|
||||
res = new ValueSetExpansionOutcome(e.getMessage() == null ? e.getClass().getName() : e.getMessage(), TerminologyServiceErrorClass.UNKNOWN, allErrors).setTxLink(txLog == null ? null : txLog.getLastId());
|
||||
res = new ValueSetExpansionOutcome((e.getMessage() == null ? e.getClass().getName() : e.getMessage()), TerminologyServiceErrorClass.UNKNOWN, allErrors).setTxLink(txLog == null ? null : txLog.getLastId());
|
||||
}
|
||||
txCache.cacheExpansion(cacheToken, res, TerminologyCache.PERMANENT);
|
||||
return res;
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package org.hl7.fhir.r5.elementmodel;
|
||||
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer;
|
||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerLanguageSession;
|
||||
import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TextUnit;
|
||||
|
||||
/**
|
||||
* in here:
|
||||
* * generateTranslations
|
||||
* * importFromTranslations
|
||||
* * stripTranslations
|
||||
* * switchLanguage
|
||||
*
|
||||
* in the validator
|
||||
*
|
||||
* @author grahamegrieve
|
||||
* generateTranslations = -langTransform export -src {src} -tgt {tgt} -dest {dest}
|
||||
* importFromTranslations = -langTransform import -src {src} -tgt {tgt} -dest {dest}
|
||||
*/
|
||||
public class LangaugeUtils {
|
||||
|
||||
IWorkerContext context;
|
||||
|
||||
|
||||
public LangaugeUtils(IWorkerContext context) {
|
||||
super();
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public void generateTranslations(Element resource, LanguageProducerLanguageSession session) {
|
||||
translate(resource, session);
|
||||
}
|
||||
|
||||
private void translate(Element element, LanguageProducerLanguageSession langSession) {
|
||||
if (element.isPrimitive() && isTranslatable(element)) {
|
||||
String base = element.primitiveValue();
|
||||
if (base != null) {
|
||||
String translation = element.getTranslation(langSession.getTargetLang());
|
||||
langSession.entry(new TextUnit(element.getPath(), base, translation));
|
||||
}
|
||||
}
|
||||
for (Element c: element.getChildren()) {
|
||||
translate(c, langSession);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTranslatable(Element element) {
|
||||
return element.getProperty().isTranslatable();
|
||||
}
|
||||
|
||||
public static boolean matches(String dstLang, String srcLang) {
|
||||
return dstLang == null ? false : dstLang.equals(srcLang);
|
||||
}
|
||||
}
|
|
@ -1810,5 +1810,15 @@ public boolean getParameterBool(String name) {
|
|||
}
|
||||
// end addition
|
||||
|
||||
public String getParameterString(String name) {
|
||||
for (ParametersParameterComponent p : getParameter()) {
|
||||
if (p.getName().equals(name)) {
|
||||
if (p.getValue() instanceof PrimitiveType)
|
||||
return ((PrimitiveType) p.getValue()).primitiveValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -102,6 +102,9 @@ public interface ValueSetExpander {
|
|||
if (!allErrors.contains(error)) {
|
||||
allErrors.add(error);
|
||||
}
|
||||
if (!errList.contains(error)) {
|
||||
errList.add(error);
|
||||
}
|
||||
}
|
||||
|
||||
public ValueSet getValueset() {
|
||||
|
|
|
@ -81,6 +81,8 @@ import org.hl7.fhir.exceptions.FHIRFormatError;
|
|||
import org.hl7.fhir.exceptions.NoTerminologyServiceException;
|
||||
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.elementmodel.LangaugeUtils;
|
||||
import org.hl7.fhir.r5.extensions.Extensions;
|
||||
import org.hl7.fhir.r5.model.BooleanType;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.Enumerations.CodeSystemContentMode;
|
||||
|
@ -98,6 +100,7 @@ import org.hl7.fhir.r5.model.PackageInformation;
|
|||
import org.hl7.fhir.r5.model.Parameters;
|
||||
import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent;
|
||||
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.ConceptReferenceComponent;
|
||||
|
@ -117,6 +120,12 @@ import com.google.errorprone.annotations.NoAllocation;
|
|||
|
||||
public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetExpander {
|
||||
|
||||
public interface IConceptFilter {
|
||||
|
||||
boolean includeConcept(CodeSystem cs, ConceptDefinitionComponent def);
|
||||
|
||||
}
|
||||
|
||||
public class PropertyFilter implements IConceptFilter {
|
||||
|
||||
private ConceptSetFilterComponent filter;
|
||||
|
@ -172,12 +181,20 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
}
|
||||
}
|
||||
|
||||
public interface IConceptFilter {
|
||||
public class RegexFilter implements IConceptFilter {
|
||||
|
||||
boolean includeConcept(CodeSystem cs, ConceptDefinitionComponent def);
|
||||
private String regex;
|
||||
|
||||
protected RegexFilter(String regex) {
|
||||
super();
|
||||
this.regex = regex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeConcept(CodeSystem cs, ConceptDefinitionComponent def) {
|
||||
return def.getCode().matches(regex);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ValueSetExpansionContainsComponent> codes = new ArrayList<ValueSet.ValueSetExpansionContainsComponent>();
|
||||
private List<ValueSetExpansionContainsComponent> roots = new ArrayList<ValueSet.ValueSetExpansionContainsComponent>();
|
||||
private Map<String, ValueSetExpansionContainsComponent> map = new HashMap<String, ValueSet.ValueSetExpansionContainsComponent>();
|
||||
|
@ -208,8 +225,9 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
maxExpansionSize = theMaxExpansionSize;
|
||||
}
|
||||
|
||||
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 deprecated, List<ValueSetExpansionPropertyComponent> vsProp) {
|
||||
private ValueSetExpansionContainsComponent addCode(String system, String code, String display, String dispLang, ValueSetExpansionContainsComponent parent, List<ConceptDefinitionDesignationComponent> designations, Parameters expParams,
|
||||
boolean isAbstract, boolean inactive, String definition, List<ValueSet> filters, boolean noInactive, boolean deprecated, List<ValueSetExpansionPropertyComponent> vsProp,
|
||||
List<ConceptPropertyComponent> csProps, List<org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent> expProps) {
|
||||
|
||||
if (filters != null && !filters.isEmpty() && !filterContainsCode(filters, system, code))
|
||||
return null;
|
||||
|
@ -227,10 +245,30 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
if (deprecated) {
|
||||
ValueSetUtilities.setDeprecated(vsProp, n);
|
||||
}
|
||||
if (expParams.getParameterBool("includeDefinition") && definition != null) {
|
||||
n.addExtension(Extensions.makeVSConceptDefinition(definition));
|
||||
}
|
||||
|
||||
// display and designations
|
||||
String srcLang = dispLang;
|
||||
String dstLang = focus.getLanguage();
|
||||
boolean usedDisplay = false;
|
||||
ConceptDefinitionDesignationComponent tu = expParams.hasParameter("displayLanguage") ? getMatchingLang(designations, expParams.getParameterString("displayLanguage")) : null;
|
||||
if (tu != null) {
|
||||
n.setDisplay(tu.getValue());
|
||||
} else if (display != null && (srcLang == null || dstLang == null || LangaugeUtils.matches(dstLang, srcLang))) {
|
||||
n.setDisplay(display);
|
||||
usedDisplay = true;
|
||||
} else {
|
||||
// we don't have a usable display
|
||||
}
|
||||
|
||||
if (expParams.getParameterBool("includeDesignations") && designations != null) {
|
||||
if (!usedDisplay && display != null) {
|
||||
n.addDesignation().setLanguage(srcLang).setValue(display);
|
||||
}
|
||||
for (ConceptDefinitionDesignationComponent t : designations) {
|
||||
if (t.getLanguage() != null || t.getValue() != null) {
|
||||
if (t != tu && (t.hasLanguage() || t.hasUse()) && t.getValue() != null) {
|
||||
ConceptReferenceDesignationComponent d = n.addDesignation();
|
||||
if (t.getLanguage() != null) {
|
||||
d.setLanguage(t.getLanguage().trim());
|
||||
|
@ -238,14 +276,32 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
if (t.getValue() != null) {
|
||||
d.setValue(t.getValue().trim());
|
||||
}
|
||||
if (t.getUse() != null) {
|
||||
d.setUse(t.getUse());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ConceptDefinitionDesignationComponent t = expParams.hasLanguage() ? getMatchingLang(designations, expParams.getLanguage()) : null;
|
||||
if (t == null)
|
||||
n.setDisplay(display);
|
||||
else
|
||||
n.setDisplay(t.getValue());
|
||||
for (ParametersParameterComponent p : expParams.getParameter()) {
|
||||
if ("property".equals(p.getName())) {
|
||||
if (csProps != null && p.hasValue()) {
|
||||
for (ConceptPropertyComponent cp : csProps) {
|
||||
if (p.getValue().primitiveValue().equals(cp.getCode())) {
|
||||
n.addProperty().setCode(cp.getCode()).setValue(cp.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (expProps != null && p.hasValue()) {
|
||||
for (org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent cp : expProps) {
|
||||
if (p.getValue().primitiveValue().equals(cp.getCode())) {
|
||||
n.addProperty(cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
String s = key(n);
|
||||
if (map.containsKey(s) || excludeKeys.contains(s)) {
|
||||
|
@ -290,12 +346,12 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
return null;
|
||||
}
|
||||
|
||||
private void addCodeAndDescendents(ValueSetExpansionContainsComponent focus, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps) throws FHIRException {
|
||||
private void addCodeAndDescendents(ValueSetExpansionContainsComponent focus, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filters, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps, ValueSet vsSrc) 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, false, vsProps);
|
||||
ValueSetExpansionContainsComponent np = addCode(focus.getSystem(), focus.getCode(), focus.getDisplay(), vsSrc.getLanguage(), parent,
|
||||
convert(focus.getDesignation()), expParams, focus.getAbstract(), focus.getInactive(), focus.getExtensionString(ToolingExtensions.EXT_DEFINITION), filters, noInactive, false, vsProps, null, focus.getProperty());
|
||||
for (ValueSetExpansionContainsComponent c : focus.getContains())
|
||||
addCodeAndDescendents(focus, np, expParams, filters, noInactive, vsProps);
|
||||
addCodeAndDescendents(focus, np, expParams, filters, noInactive, vsProps, vsSrc);
|
||||
}
|
||||
|
||||
private List<ConceptDefinitionDesignationComponent> convert(List<ConceptReferenceDesignationComponent> designations) {
|
||||
|
@ -310,7 +366,8 @@ 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, List<ValueSetExpansionPropertyComponent> vsProps) 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()))
|
||||
|
@ -321,7 +378,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
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);
|
||||
np = addCode(system, def.getCode(), def.getDisplay(), cs.getLanguage(), parent, def.getDesignation(), expParams, abs, inc, def.getDefinition(), filters, noInactive, dep, vsProps, def.getProperty(), null);
|
||||
}
|
||||
for (ConceptDefinitionComponent c : def.getConcept()) {
|
||||
addCodeAndDescendents(cs, system, c, np, expParams, filters, exclusion, filterFunc, noInactive, vsProps);
|
||||
|
@ -334,7 +391,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
|
||||
}
|
||||
|
||||
private void addCodes(ValueSetExpansionComponent expand, List<ValueSetExpansionParameterComponent> params, Parameters expParams, List<ValueSet> filters, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps) throws ETooCostly, FHIRException {
|
||||
private void addCodes(ValueSetExpansionComponent expand, List<ValueSetExpansionParameterComponent> params, Parameters expParams, List<ValueSet> filters, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps, ValueSet vsSrc) throws ETooCostly, FHIRException {
|
||||
if (expand != null) {
|
||||
if (expand.getContains().size() > maxExpansionSize)
|
||||
throw failCostly("Too many codes to display (>" + Integer.toString(expand.getContains().size()) + ")");
|
||||
|
@ -343,7 +400,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
params.add(p);
|
||||
}
|
||||
|
||||
copyImportContains(expand.getContains(), null, expParams, filters, noInactive, vsProps);
|
||||
copyImportContains(expand.getContains(), null, expParams, filters, noInactive, vsProps, vsSrc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -432,8 +489,12 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
focus.getExpansion().setTimestampElement(DateTimeType.now());
|
||||
focus.getExpansion().setIdentifier(Factory.createUUID());
|
||||
for (ParametersParameterComponent p : expParams.getParameter()) {
|
||||
if (Utilities.existsInList(p.getName(), "includeDesignations", "excludeNested", "activeOnly"))
|
||||
if (Utilities.existsInList(p.getName(), "includeDesignations", "excludeNested", "activeOnly")) {
|
||||
focus.getExpansion().addParameter().setName(p.getName()).setValue(p.getValue());
|
||||
}
|
||||
}
|
||||
if (expParams.hasLanguage()) {
|
||||
focus.setLanguage(expParams.getLanguage());
|
||||
}
|
||||
|
||||
if (source.hasCompose()) {
|
||||
|
@ -591,11 +652,12 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
}
|
||||
}
|
||||
|
||||
private void copyImportContains(List<ValueSetExpansionContainsComponent> list, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filter, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps) throws FHIRException {
|
||||
private void copyImportContains(List<ValueSetExpansionContainsComponent> list, ValueSetExpansionContainsComponent parent, Parameters expParams, List<ValueSet> filter, boolean noInactive, List<ValueSetExpansionPropertyComponent> vsProps, ValueSet vsSrc) 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, false, vsProps);
|
||||
copyImportContains(c.getContains(), np, expParams, filter, noInactive, vsProps);
|
||||
ValueSetExpansionContainsComponent np = addCode(c.getSystem(), c.getCode(), c.getDisplay(), vsSrc.getLanguage(), parent, null, expParams, c.getAbstract(), c.getInactive(), c.getExtensionString(ToolingExtensions.EXT_DEFINITION),
|
||||
filter, noInactive, false, vsProps, null, c.getProperty());
|
||||
copyImportContains(c.getContains(), np, expParams, filter, noInactive, vsProps, vsSrc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -612,13 +674,13 @@ 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, base.getExpansion().getProperty());
|
||||
copyImportContains(base.getExpansion().getContains(), null, expParams, imports, noInactive, base.getExpansion().getProperty(), base);
|
||||
} 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, valueSet.getExpansion().getProperty());
|
||||
} else {
|
||||
doInternalIncludeCodes(inc, exp, expParams, imports, cs, noInactive);
|
||||
doInternalIncludeCodes(inc, exp, expParams, imports, cs, noInactive, valueSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -653,7 +715,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
}
|
||||
}
|
||||
for (ValueSetExpansionContainsComponent cc : vs.getExpansion().getContains()) {
|
||||
addCodeAndDescendents(cc, null, expParams, imports, noInactive, vsProps);
|
||||
addCodeAndDescendents(cc, null, expParams, imports, noInactive, vsProps, vs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -666,7 +728,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
return false;
|
||||
}
|
||||
|
||||
public void doInternalIncludeCodes(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, List<ValueSet> imports, CodeSystem cs, boolean noInactive) throws NoTerminologyServiceException, TerminologyServiceException, FHIRException {
|
||||
public void doInternalIncludeCodes(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, List<ValueSet> imports, CodeSystem cs, boolean noInactive, Resource vsSrc) throws NoTerminologyServiceException, TerminologyServiceException, FHIRException {
|
||||
if (cs == null) {
|
||||
if (context.isNoTerminologyServer())
|
||||
throw failTSE("Unable to find code system " + inc.getSystem().toString());
|
||||
|
@ -712,7 +774,8 @@ 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, false, exp.getProperty());
|
||||
addCode(inc.getSystem(), c.getCode(), !Utilities.noString(c.getDisplay()) ? c.getDisplay() : def == null ? null : def.getDisplay(), c.hasDisplay() ? vsSrc.getLanguage() : cs.getLanguage(), null, mergeDesignations(def, convertDesignations(c.getDesignation())),
|
||||
expParams, false, inactive, def == null ? null : def.getDefinition(), imports, noInactive, false, exp.getProperty(), def != null ? def.getProperty() : null, null);
|
||||
}
|
||||
}
|
||||
if (inc.getFilter().size() > 1) {
|
||||
|
@ -758,8 +821,8 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
if (def != null) {
|
||||
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, false, exp.getProperty());
|
||||
addCode(inc.getSystem(), def.getCode(), def.getDisplay(), cs.getLanguage(), null, def.getDesignation(), expParams, CodeSystemUtilities.isNotSelectable(cs, def), CodeSystemUtilities.isInactive(cs, def),
|
||||
def.getDefinition(), imports, noInactive, false, exp.getProperty(), def.getProperty(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -767,12 +830,24 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx
|
|||
for (ConceptDefinitionComponent def : cs.getConcept()) {
|
||||
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new PropertyFilter(fc, getPropertyDefinition(cs, fc.getProperty())), noInactive, exp.getProperty());
|
||||
}
|
||||
} else if ("regex".equals(fc.getProperty()) && fc.getOp() == FilterOperator.EQUAL) {
|
||||
for (ConceptDefinitionComponent def : cs.getConcept()) {
|
||||
addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new RegexFilter(fc.getValue()), noInactive, exp.getProperty());
|
||||
}
|
||||
} else {
|
||||
throw fail("Search by property[" + fc.getProperty() + "] and op[" + fc.getOp() + "] is not supported yet");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<ConceptDefinitionDesignationComponent> mergeDesignations(ConceptDefinitionComponent def,
|
||||
List<ConceptDefinitionDesignationComponent> list) {
|
||||
List<ConceptDefinitionDesignationComponent> res = new ArrayList<>();
|
||||
res.addAll(def.getDesignation());
|
||||
res.addAll(list);
|
||||
return res;
|
||||
}
|
||||
|
||||
private PropertyComponent getPropertyDefinition(CodeSystem cs, String property) {
|
||||
for (PropertyComponent cp : cs.getProperty()) {
|
||||
if (cp.getCode().equals(property)) {
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.hl7.fhir.r5.test.utils;
|
|||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.utilities.CSFile;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.ToolGlobalSettings;
|
||||
|
@ -181,7 +182,7 @@ public class CompareUtilities extends BaseTestingUtilities {
|
|||
String diff = null;
|
||||
if (System.getProperty("os.name").contains("Linux"))
|
||||
diff = Utilities.path("/", "usr", "bin", "meld");
|
||||
else {
|
||||
else if (System.getenv("ProgramFiles(X86)") != null) {
|
||||
if (Utilities.checkFile("WinMerge", Utilities.path(System.getenv("ProgramFiles(X86)"), "WinMerge"), "\\WinMergeU.exe", null))
|
||||
diff = Utilities.path(System.getenv("ProgramFiles(X86)"), "WinMerge", "WinMergeU.exe");
|
||||
else if (Utilities.checkFile("WinMerge", Utilities.path(System.getenv("ProgramFiles(X86)"), "Meld"), "\\Meld.exe", null))
|
||||
|
@ -271,7 +272,7 @@ public class CompareUtilities extends BaseTestingUtilities {
|
|||
String actualJsonString = actualJsonPrimitive.getAsString();
|
||||
String expectedJsonString = expectedJsonPrimitive.getAsString();
|
||||
if (!(actualJsonString.contains("<div") && expectedJsonString.contains("<div")))
|
||||
if (!actualJsonString.equals(expectedJsonString))
|
||||
if (!matches(actualJsonString, expectedJsonString))
|
||||
if (!sameBytes(unBase64(actualJsonString), unBase64(expectedJsonString)))
|
||||
return createNotEqualMessage("string property values differ at " + path, expectedJsonString, actualJsonString);
|
||||
} else if (actualJsonPrimitive.isNumber() && expectedJsonPrimitive.isNumber()) {
|
||||
|
@ -301,6 +302,20 @@ public class CompareUtilities extends BaseTestingUtilities {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static boolean matches(String actualJsonString, String expectedJsonString) {
|
||||
if (expectedJsonString.startsWith("$") && expectedJsonString.endsWith("$")) {
|
||||
switch (expectedJsonString) {
|
||||
case "$$" : return true;
|
||||
case "$instant$": return actualJsonString.matches("([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\\.[0-9]{1,9})?(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))");
|
||||
case "$uuid$": return actualJsonString.matches("urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}");
|
||||
default:
|
||||
throw new Error("Unhandled template: "+expectedJsonString);
|
||||
}
|
||||
} else {
|
||||
return actualJsonString.equals(expectedJsonString);
|
||||
}
|
||||
}
|
||||
|
||||
public static String checkTextIsSame(String expected, String actual) throws JsonSyntaxException, FileNotFoundException, IOException {
|
||||
return checkTextIsSame(expected, actual, true);
|
||||
}
|
||||
|
@ -349,4 +364,5 @@ public class CompareUtilities extends BaseTestingUtilities {
|
|||
return createNotEqualMessage("Strings differ in length but match to the end of the shortest.", Integer.toString(expectedString.length()), Integer.toString(actualString.length()));
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,5 +17,5 @@ public class TestModules {
|
|||
VALIDATION_MODULE
|
||||
};
|
||||
|
||||
public static final List<String> JUNIT4_CLASSNAMES = Arrays.asList("org.hl7.fhir.validation.tests.ValidationTests");
|
||||
public static final List<String> JUNIT4_CLASSNAMES = Arrays.asList("org.hl7.fhir.validation.tests.ValidationTests", "org.hl7.fhir.terminologies.tests.TerminologyServiceTests");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,207 @@
|
|||
package org.hl7.fhir.terminology.tests;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50;
|
||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_50;
|
||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50;
|
||||
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.formats.JsonParser;
|
||||
import org.hl7.fhir.r5.formats.XmlParser;
|
||||
import org.hl7.fhir.r5.model.Constants;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||
import org.hl7.fhir.r5.test.utils.CompareUtilities;
|
||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||
import org.hl7.fhir.terminology.tests.TerminologyServiceTests.JsonObjectPair;
|
||||
import org.hl7.fhir.utilities.FhirPublication;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.json.model.JsonObject;
|
||||
import org.hl7.fhir.validation.ValidationEngine;
|
||||
import org.hl7.fhir.validation.tests.ValidationEngineTests;
|
||||
import org.hl7.fhir.validation.tests.utilities.TestUtilities;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class TerminologyServiceTests {
|
||||
|
||||
public static class JsonObjectPair {
|
||||
public JsonObjectPair(JsonObject suite, JsonObject test) {
|
||||
this.suite = suite;
|
||||
this.test = test;
|
||||
}
|
||||
private JsonObject suite;
|
||||
private JsonObject test;
|
||||
}
|
||||
|
||||
@Parameters(name = "{index}: id {0}")
|
||||
public static Iterable<Object[]> data() throws IOException {
|
||||
|
||||
String contents = TestingUtilities.loadTestResource("tx", "test-cases.json");
|
||||
|
||||
Map<String, JsonObjectPair> examples = new HashMap<String, JsonObjectPair>();
|
||||
manifest = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(contents);
|
||||
for (org.hl7.fhir.utilities.json.model.JsonObject suite : manifest.getJsonObjects("suites")) {
|
||||
String sn = suite.asString("name");
|
||||
for (org.hl7.fhir.utilities.json.model.JsonObject test : suite.getJsonObjects("tests")) {
|
||||
String tn = test.asString("name");
|
||||
examples.put(sn+"."+tn, new JsonObjectPair(suite, test));
|
||||
}
|
||||
}
|
||||
|
||||
List<String> names = new ArrayList<String>(examples.size());
|
||||
names.addAll(examples.keySet());
|
||||
Collections.sort(names);
|
||||
|
||||
List<Object[]> objects = new ArrayList<Object[]>(examples.size());
|
||||
for (String id : names) {
|
||||
objects.add(new Object[]{id, examples.get(id)});
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
|
||||
private static org.hl7.fhir.utilities.json.model.JsonObject manifest;
|
||||
private JsonObjectPair setup;
|
||||
private String version;
|
||||
private String name;
|
||||
|
||||
|
||||
private static ValidationEngine baseEngine;
|
||||
|
||||
public TerminologyServiceTests(String name, JsonObjectPair setup) {
|
||||
this.name = name;
|
||||
this.setup = setup;
|
||||
version = "5.0.0";
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
if (baseEngine == null) {
|
||||
baseEngine = TestUtilities.getValidationEngine("hl7.fhir.r5.core#5.0.0", ValidationEngineTests.DEF_TX, null, FhirPublication.R5, true, "5.0.0");
|
||||
}
|
||||
ValidationEngine engine = new ValidationEngine(this.baseEngine);
|
||||
for (String s : setup.suite.forceArray("setup").asStrings()) {
|
||||
Resource res = loadResource(s);
|
||||
engine.seeResource(res);
|
||||
}
|
||||
Resource req = loadResource(setup.test.asString("request"));
|
||||
String resp = TestingUtilities.loadTestResource("tx", setup.test.asString("response"));
|
||||
if (setup.test.asString("operation").equals("expand")) {
|
||||
expand(engine, req, resp, setup.test.asString("response"));
|
||||
} else if (setup.test.asString("operation").equals("validate-code")) {
|
||||
validate(engine, req, resp);
|
||||
} else {
|
||||
Assertions.fail("Unknown Operation "+setup.test.asString("operation"));
|
||||
}
|
||||
}
|
||||
|
||||
private void expand(ValidationEngine engine, Resource req, String resp, String fn) throws IOException {
|
||||
String fp = Utilities.path("[tmp]", "tx", fn);
|
||||
File fo = new File(fp);
|
||||
if (fo.exists()) {
|
||||
fo.delete();
|
||||
}
|
||||
|
||||
org.hl7.fhir.r5.model.Parameters p = ( org.hl7.fhir.r5.model.Parameters) req;
|
||||
ValueSet vs = engine.getContext().fetchResource(ValueSet.class, p.getParameterValue("url").primitiveValue());
|
||||
boolean hierarchical = p.hasParameter("excludeNested") ? p.getParameterBool("excludeNested") == false : true;
|
||||
Assertions.assertNotNull(vs);
|
||||
ValueSetExpansionOutcome vse = engine.getContext().expandVS(vs, false, hierarchical, false, p);
|
||||
if (resp.contains("\"ValueSet\"")) {
|
||||
if (vse.getValueset() == null) {
|
||||
Assertions.fail(vse.getError());
|
||||
} else {
|
||||
if (!p.hasParameter("excludeNested")) {
|
||||
removeParameter(vse.getValueset(), "excludeNested");
|
||||
}
|
||||
String vsj = new JsonParser().setOutputStyle(OutputStyle.PRETTY).composeString(vse.getValueset());
|
||||
String diff = CompareUtilities.checkJsonSrcIsSame(resp, vsj);
|
||||
if (diff != null) {
|
||||
Utilities.createDirectory(Utilities.getDirectoryForFile(fp));
|
||||
TextFile.stringToFile(vsj, fp);
|
||||
}
|
||||
Assertions.assertTrue(diff == null, diff);
|
||||
}
|
||||
} else {
|
||||
Assertions.fail("expand error not done yet");
|
||||
}
|
||||
}
|
||||
|
||||
private void removeParameter(ValueSet valueset, String name) {
|
||||
for (ValueSetExpansionParameterComponent exp : valueset.getExpansion().getParameter()) {
|
||||
if (exp.getName().equals(name)) {
|
||||
valueset.getExpansion().getParameter().remove(exp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validate(ValidationEngine engine2, Resource req, String resp) {
|
||||
Assertions.fail("validate not done yet");
|
||||
}
|
||||
|
||||
public Resource loadResource(String filename) throws IOException, FHIRFormatError, FileNotFoundException, FHIRException, DefinitionException {
|
||||
String contents = TestingUtilities.loadTestResource("tx", filename);
|
||||
try (InputStream inputStream = IOUtils.toInputStream(contents, Charsets.UTF_8)) {
|
||||
if (filename.contains(".json")) {
|
||||
if (Constants.VERSION.equals(version) || "5.0".equals(version))
|
||||
return new JsonParser().parse(inputStream);
|
||||
else if (org.hl7.fhir.dstu3.model.Constants.VERSION.equals(version) || "3.0".equals(version))
|
||||
return VersionConvertorFactory_30_50.convertResource(new org.hl7.fhir.dstu3.formats.JsonParser().parse(inputStream));
|
||||
else if (org.hl7.fhir.dstu2016may.model.Constants.VERSION.equals(version) || "1.4".equals(version))
|
||||
return VersionConvertorFactory_14_50.convertResource(new org.hl7.fhir.dstu2016may.formats.JsonParser().parse(inputStream));
|
||||
else if (org.hl7.fhir.dstu2.model.Constants.VERSION.equals(version) || "1.0".equals(version))
|
||||
return VersionConvertorFactory_10_50.convertResource(new org.hl7.fhir.dstu2.formats.JsonParser().parse(inputStream));
|
||||
else if (org.hl7.fhir.r4.model.Constants.VERSION.equals(version) || "4.0".equals(version))
|
||||
return VersionConvertorFactory_40_50.convertResource(new org.hl7.fhir.r4.formats.JsonParser().parse(inputStream));
|
||||
else
|
||||
throw new FHIRException("unknown version " + version);
|
||||
} else {
|
||||
if (Constants.VERSION.equals(version) || "5.0".equals(version))
|
||||
return new XmlParser().parse(inputStream);
|
||||
else if (org.hl7.fhir.dstu3.model.Constants.VERSION.equals(version) || "3.0".equals(version))
|
||||
return VersionConvertorFactory_30_50.convertResource(new org.hl7.fhir.dstu3.formats.XmlParser().parse(inputStream));
|
||||
else if (org.hl7.fhir.dstu2016may.model.Constants.VERSION.equals(version) || "1.4".equals(version))
|
||||
return VersionConvertorFactory_14_50.convertResource(new org.hl7.fhir.dstu2016may.formats.XmlParser().parse(inputStream));
|
||||
else if (org.hl7.fhir.dstu2.model.Constants.VERSION.equals(version) || "1.0".equals(version))
|
||||
return VersionConvertorFactory_10_50.convertResource(new org.hl7.fhir.dstu2.formats.XmlParser().parse(inputStream));
|
||||
else if (org.hl7.fhir.r4.model.Constants.VERSION.equals(version) || "4.0".equals(version))
|
||||
return VersionConvertorFactory_40_50.convertResource(new org.hl7.fhir.r4.formats.XmlParser().parse(inputStream));
|
||||
else
|
||||
throw new FHIRException("unknown version " + version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void saveWhenDone() throws IOException {
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue