Support displayLanguage through validator framework
This commit is contained in:
parent
4ff9e0626a
commit
23eb7282bd
|
@ -82,6 +82,7 @@ import org.hl7.fhir.r5.model.UriType;
|
||||||
import org.hl7.fhir.r5.model.ValueSet;
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||||
|
import org.hl7.fhir.r5.terminologies.TerminologyServiceOptions;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||||
import org.hl7.fhir.r5.utils.NarrativeGenerator;
|
import org.hl7.fhir.r5.utils.NarrativeGenerator;
|
||||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||||
|
@ -215,6 +216,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
private ProfileKnowledgeProvider pkp;
|
private ProfileKnowledgeProvider pkp;
|
||||||
private boolean igmode;
|
private boolean igmode;
|
||||||
private boolean exception;
|
private boolean exception;
|
||||||
|
private TerminologyServiceOptions terminologyServiceOptions = new TerminologyServiceOptions();
|
||||||
|
|
||||||
public ProfileUtilities(IWorkerContext context, List<ValidationMessage> messages, ProfileKnowledgeProvider pkp) {
|
public ProfileUtilities(IWorkerContext context, List<ValidationMessage> messages, ProfileKnowledgeProvider pkp) {
|
||||||
super();
|
super();
|
||||||
|
@ -2787,13 +2789,13 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
private Piece describeCoded(HierarchicalTableGenerator gen, Type fixed) {
|
private Piece describeCoded(HierarchicalTableGenerator gen, Type fixed) {
|
||||||
if (fixed instanceof Coding) {
|
if (fixed instanceof Coding) {
|
||||||
Coding c = (Coding) fixed;
|
Coding c = (Coding) fixed;
|
||||||
ValidationResult vr = context.validateCode(c.getSystem(), c.getCode(), c.getDisplay());
|
ValidationResult vr = context.validateCode(terminologyServiceOptions , c.getSystem(), c.getCode(), c.getDisplay());
|
||||||
if (vr.getDisplay() != null)
|
if (vr.getDisplay() != null)
|
||||||
return gen.new Piece(null, " ("+vr.getDisplay()+")", null).addStyle("color: darkgreen");
|
return gen.new Piece(null, " ("+vr.getDisplay()+")", null).addStyle("color: darkgreen");
|
||||||
} else if (fixed instanceof CodeableConcept) {
|
} else if (fixed instanceof CodeableConcept) {
|
||||||
CodeableConcept cc = (CodeableConcept) fixed;
|
CodeableConcept cc = (CodeableConcept) fixed;
|
||||||
for (Coding c : cc.getCoding()) {
|
for (Coding c : cc.getCoding()) {
|
||||||
ValidationResult vr = context.validateCode(c.getSystem(), c.getCode(), c.getDisplay());
|
ValidationResult vr = context.validateCode(terminologyServiceOptions, c.getSystem(), c.getCode(), c.getDisplay());
|
||||||
if (vr.getDisplay() != null)
|
if (vr.getDisplay() != null)
|
||||||
return gen.new Piece(null, " ("+vr.getDisplay()+")", null).addStyle("color: darkgreen");
|
return gen.new Piece(null, " ("+vr.getDisplay()+")", null).addStyle("color: darkgreen");
|
||||||
}
|
}
|
||||||
|
@ -4236,4 +4238,16 @@ public class ProfileUtilities extends TranslatingUtilities {
|
||||||
public void setThrowException(boolean exception) {
|
public void setThrowException(boolean exception) {
|
||||||
this.exception = exception;
|
this.exception = exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public TerminologyServiceOptions getTerminologyServiceOptions() {
|
||||||
|
return terminologyServiceOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setTerminologyServiceOptions(TerminologyServiceOptions terminologyServiceOptions) {
|
||||||
|
this.terminologyServiceOptions = terminologyServiceOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetComposeComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ValueSetComposeComponent;
|
||||||
import org.hl7.fhir.r5.terminologies.TerminologyClient;
|
import org.hl7.fhir.r5.terminologies.TerminologyClient;
|
||||||
|
import org.hl7.fhir.r5.terminologies.TerminologyServiceOptions;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetCheckerSimple;
|
import org.hl7.fhir.r5.terminologies.ValueSetCheckerSimple;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||||
|
@ -458,39 +459,39 @@ public abstract class BaseWorkerContext implements IWorkerContext {
|
||||||
// --- validate code -------------------------------------------------------------------------------
|
// --- validate code -------------------------------------------------------------------------------
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValidationResult validateCode(String system, String code, String display) {
|
public ValidationResult validateCode(TerminologyServiceOptions options, String system, String code, String display) {
|
||||||
Coding c = new Coding(system, code, display);
|
Coding c = new Coding(system, code, display);
|
||||||
return validateCode(c, null);
|
return validateCode(options, c, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValidationResult validateCode(String system, String code, String display, ValueSet vs) {
|
public ValidationResult validateCode(TerminologyServiceOptions options, String system, String code, String display, ValueSet vs) {
|
||||||
Coding c = new Coding(system, code, display);
|
Coding c = new Coding(system, code, display);
|
||||||
return validateCode(c, vs);
|
return validateCode(options, c, vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValidationResult validateCode(String code, ValueSet vs) {
|
public ValidationResult validateCode(TerminologyServiceOptions options, String code, ValueSet vs) {
|
||||||
Coding c = new Coding(null, code, null);
|
Coding c = new Coding(null, code, null);
|
||||||
return doValidateCode(c, vs, true);
|
return doValidateCode(options, c, vs, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValidationResult validateCode(String system, String code, String display, ConceptSetComponent vsi) {
|
public ValidationResult validateCode(TerminologyServiceOptions options, String system, String code, String display, ConceptSetComponent vsi) {
|
||||||
Coding c = new Coding(system, code, display);
|
Coding c = new Coding(system, code, display);
|
||||||
ValueSet vs = new ValueSet();
|
ValueSet vs = new ValueSet();
|
||||||
vs.setUrl(Utilities.makeUuidUrn());
|
vs.setUrl(Utilities.makeUuidUrn());
|
||||||
vs.getCompose().addInclude(vsi);
|
vs.getCompose().addInclude(vsi);
|
||||||
return validateCode(c, vs);
|
return validateCode(options, c, vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValidationResult validateCode(Coding code, ValueSet vs) {
|
public ValidationResult validateCode(TerminologyServiceOptions options, Coding code, ValueSet vs) {
|
||||||
return doValidateCode(code, vs, false);
|
return doValidateCode(options, code, vs, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValidationResult doValidateCode(Coding code, ValueSet vs, boolean implySystem) {
|
public ValidationResult doValidateCode(TerminologyServiceOptions options, Coding code, ValueSet vs, boolean implySystem) {
|
||||||
CacheToken cacheToken = txCache != null ? txCache.generateValidationToken(code, vs) : null;
|
CacheToken cacheToken = txCache != null ? txCache.generateValidationToken(options, code, vs) : null;
|
||||||
ValidationResult res = null;
|
ValidationResult res = null;
|
||||||
if (txCache != null)
|
if (txCache != null)
|
||||||
res = txCache.getValidation(cacheToken);
|
res = txCache.getValidation(cacheToken);
|
||||||
|
@ -499,7 +500,7 @@ public abstract class BaseWorkerContext implements IWorkerContext {
|
||||||
|
|
||||||
// ok, first we try to validate locally
|
// ok, first we try to validate locally
|
||||||
try {
|
try {
|
||||||
ValueSetCheckerSimple vsc = new ValueSetCheckerSimple(vs, this);
|
ValueSetCheckerSimple vsc = new ValueSetCheckerSimple(options, vs, this);
|
||||||
res = vsc.validateCode(code);
|
res = vsc.validateCode(code);
|
||||||
if (txCache != null)
|
if (txCache != null)
|
||||||
txCache.cacheValidation(cacheToken, res, TerminologyCache.TRANSIENT);
|
txCache.cacheValidation(cacheToken, res, TerminologyCache.TRANSIENT);
|
||||||
|
@ -520,6 +521,8 @@ public abstract class BaseWorkerContext implements IWorkerContext {
|
||||||
pIn.addParameter().setName("coding").setValue(code);
|
pIn.addParameter().setName("coding").setValue(code);
|
||||||
if (implySystem)
|
if (implySystem)
|
||||||
pIn.addParameter().setName("implySystem").setValue(new BooleanType(true));
|
pIn.addParameter().setName("implySystem").setValue(new BooleanType(true));
|
||||||
|
if (options != null)
|
||||||
|
options.updateParameters(pIn);
|
||||||
res = validateOnServer(vs, pIn);
|
res = validateOnServer(vs, pIn);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
res = new ValidationResult(IssueSeverity.ERROR, e.getMessage() == null ? e.getClass().getName() : e.getMessage()).setTxLink(txLog == null ? null : txLog.getLastId());
|
res = new ValidationResult(IssueSeverity.ERROR, e.getMessage() == null ? e.getClass().getName() : e.getMessage()).setTxLink(txLog == null ? null : txLog.getLastId());
|
||||||
|
@ -530,15 +533,15 @@ public abstract class BaseWorkerContext implements IWorkerContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValidationResult validateCode(CodeableConcept code, ValueSet vs) {
|
public ValidationResult validateCode(TerminologyServiceOptions options, CodeableConcept code, ValueSet vs) {
|
||||||
CacheToken cacheToken = txCache.generateValidationToken(code, vs);
|
CacheToken cacheToken = txCache.generateValidationToken(options, code, vs);
|
||||||
ValidationResult res = txCache.getValidation(cacheToken);
|
ValidationResult res = txCache.getValidation(cacheToken);
|
||||||
if (res != null)
|
if (res != null)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
// ok, first we try to validate locally
|
// ok, first we try to validate locally
|
||||||
try {
|
try {
|
||||||
ValueSetCheckerSimple vsc = new ValueSetCheckerSimple(vs, this);
|
ValueSetCheckerSimple vsc = new ValueSetCheckerSimple(options, vs, this);
|
||||||
res = vsc.validateCode(code);
|
res = vsc.validateCode(code);
|
||||||
txCache.cacheValidation(cacheToken, res, TerminologyCache.TRANSIENT);
|
txCache.cacheValidation(cacheToken, res, TerminologyCache.TRANSIENT);
|
||||||
return res;
|
return res;
|
||||||
|
@ -552,6 +555,8 @@ public abstract class BaseWorkerContext implements IWorkerContext {
|
||||||
try {
|
try {
|
||||||
Parameters pIn = new Parameters();
|
Parameters pIn = new Parameters();
|
||||||
pIn.addParameter().setName("codeableConcept").setValue(code);
|
pIn.addParameter().setName("codeableConcept").setValue(code);
|
||||||
|
if (options != null)
|
||||||
|
options.updateParameters(pIn);
|
||||||
res = validateOnServer(vs, pIn);
|
res = validateOnServer(vs, pIn);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
res = new ValidationResult(IssueSeverity.ERROR, e.getMessage() == null ? e.getClass().getName() : e.getMessage()).setTxLink(txLog.getLastId());
|
res = new ValidationResult(IssueSeverity.ERROR, e.getMessage() == null ? e.getClass().getName() : e.getMessage()).setTxLink(txLog.getLastId());
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
import org.hl7.fhir.r5.model.StructureMap;
|
import org.hl7.fhir.r5.model.StructureMap;
|
||||||
import org.hl7.fhir.r5.model.ValueSet;
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||||
|
import org.hl7.fhir.r5.terminologies.TerminologyServiceOptions;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||||
import org.hl7.fhir.r5.utils.INarrativeGenerator;
|
import org.hl7.fhir.r5.utils.INarrativeGenerator;
|
||||||
|
@ -371,7 +372,7 @@ public interface IWorkerContext {
|
||||||
* @param display
|
* @param display
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public ValidationResult validateCode(String system, String code, String display);
|
public ValidationResult validateCode(TerminologyServiceOptions options, String system, String code, String display);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validation of a code - consult the terminology service
|
* Validation of a code - consult the terminology service
|
||||||
|
@ -387,10 +388,10 @@ public interface IWorkerContext {
|
||||||
* @param display
|
* @param display
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public ValidationResult validateCode(String system, String code, String display, ValueSet vs);
|
public ValidationResult validateCode(TerminologyServiceOptions options, String system, String code, String display, ValueSet vs);
|
||||||
public ValidationResult validateCode(String code, ValueSet vs);
|
public ValidationResult validateCode(TerminologyServiceOptions options, String code, ValueSet vs);
|
||||||
public ValidationResult validateCode(Coding code, ValueSet vs);
|
public ValidationResult validateCode(TerminologyServiceOptions options, Coding code, ValueSet vs);
|
||||||
public ValidationResult validateCode(CodeableConcept code, ValueSet vs);
|
public ValidationResult validateCode(TerminologyServiceOptions options, CodeableConcept code, ValueSet vs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validation of a code - consult the terminology service
|
* Validation of a code - consult the terminology service
|
||||||
|
@ -406,7 +407,7 @@ public interface IWorkerContext {
|
||||||
* @param display
|
* @param display
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public ValidationResult validateCode(String system, String code, String display, ConceptSetComponent vsi);
|
public ValidationResult validateCode(TerminologyServiceOptions options, String system, String code, String display, ConceptSetComponent vsi);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the recommended tla for the type
|
* returns the recommended tla for the type
|
||||||
|
|
|
@ -43,6 +43,7 @@ import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||||
|
import org.hl7.fhir.r5.terminologies.TerminologyServiceOptions;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||||
|
@ -111,7 +112,7 @@ public class TerminologyCache {
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CacheToken generateValidationToken(Coding code, ValueSet vs) {
|
public CacheToken generateValidationToken(TerminologyServiceOptions options, Coding code, ValueSet vs) {
|
||||||
CacheToken ct = new CacheToken();
|
CacheToken ct = new CacheToken();
|
||||||
if (code.hasSystem())
|
if (code.hasSystem())
|
||||||
ct.name = getNameForSystem(code.getSystem());
|
ct.name = getNameForSystem(code.getSystem());
|
||||||
|
@ -121,7 +122,7 @@ public class TerminologyCache {
|
||||||
json.setOutputStyle(OutputStyle.PRETTY);
|
json.setOutputStyle(OutputStyle.PRETTY);
|
||||||
ValueSet vsc = getVSEssense(vs);
|
ValueSet vsc = getVSEssense(vs);
|
||||||
try {
|
try {
|
||||||
ct.request = "{\"code\" : "+json.composeString(code, "code")+", \"valueSet\" :"+(vsc == null ? "null" : json.composeString(vsc))+"}";
|
ct.request = "{\"code\" : "+json.composeString(code, "code")+", \"valueSet\" :"+(vsc == null ? "null" : json.composeString(vsc))+(options == null ? "" : ", "+options.toJson())+"}";
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new Error(e);
|
throw new Error(e);
|
||||||
}
|
}
|
||||||
|
@ -129,7 +130,7 @@ public class TerminologyCache {
|
||||||
return ct;
|
return ct;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CacheToken generateValidationToken(CodeableConcept code, ValueSet vs) {
|
public CacheToken generateValidationToken(TerminologyServiceOptions options, CodeableConcept code, ValueSet vs) {
|
||||||
CacheToken ct = new CacheToken();
|
CacheToken ct = new CacheToken();
|
||||||
for (Coding c : code.getCoding()) {
|
for (Coding c : code.getCoding()) {
|
||||||
if (c.hasSystem())
|
if (c.hasSystem())
|
||||||
|
@ -139,7 +140,7 @@ public class TerminologyCache {
|
||||||
json.setOutputStyle(OutputStyle.PRETTY);
|
json.setOutputStyle(OutputStyle.PRETTY);
|
||||||
ValueSet vsc = getVSEssense(vs);
|
ValueSet vsc = getVSEssense(vs);
|
||||||
try {
|
try {
|
||||||
ct.request = "{\"code\" : "+json.composeString(code, "codeableConcept")+", \"valueSet\" :"+json.composeString(vsc)+"}";
|
ct.request = "{\"code\" : "+json.composeString(code, "codeableConcept")+", \"valueSet\" :"+json.composeString(vsc)+(options == null ? "" : ", "+options.toJson())+"}";
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new Error(e);
|
throw new Error(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package org.hl7.fhir.r5.terminologies;
|
||||||
|
|
||||||
|
import org.fhir.ucum.Utilities;
|
||||||
|
import org.hl7.fhir.r5.model.Parameters;
|
||||||
|
|
||||||
|
public class TerminologyServiceOptions {
|
||||||
|
private String language;
|
||||||
|
|
||||||
|
public TerminologyServiceOptions() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerminologyServiceOptions(String language) {
|
||||||
|
super();
|
||||||
|
this.language = language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLanguage() {
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLanguage(String language) {
|
||||||
|
this.language = language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toJson() {
|
||||||
|
return "\"lang\":\""+language+"\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateParameters(Parameters pIn) {
|
||||||
|
if (!Utilities.noString(language))
|
||||||
|
pIn.addParameter("displayLanguage", language);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -51,10 +51,12 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
|
||||||
private ValueSet valueset;
|
private ValueSet valueset;
|
||||||
private IWorkerContext context;
|
private IWorkerContext context;
|
||||||
private Map<String, ValueSetCheckerSimple> inner = new HashMap<>();
|
private Map<String, ValueSetCheckerSimple> inner = new HashMap<>();
|
||||||
|
private TerminologyServiceOptions options;
|
||||||
|
|
||||||
public ValueSetCheckerSimple(ValueSet source, IWorkerContext context) {
|
public ValueSetCheckerSimple(TerminologyServiceOptions options, ValueSet source, IWorkerContext context) {
|
||||||
this.valueset = source;
|
this.valueset = source;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
this.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValidationResult validateCode(CodeableConcept code) throws FHIRException {
|
public ValidationResult validateCode(CodeableConcept code) throws FHIRException {
|
||||||
|
@ -425,7 +427,7 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
|
||||||
return inner.get(url);
|
return inner.get(url);
|
||||||
}
|
}
|
||||||
ValueSet vs = context.fetchResource(ValueSet.class, url);
|
ValueSet vs = context.fetchResource(ValueSet.class, url);
|
||||||
ValueSetCheckerSimple vsc = new ValueSetCheckerSimple(vs, context);
|
ValueSetCheckerSimple vsc = new ValueSetCheckerSimple(options, vs, context);
|
||||||
inner.put(url, vsc);
|
inner.put(url, vsc);
|
||||||
return vsc;
|
return vsc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ import org.hl7.fhir.r5.model.TemporalPrecisionEnum;
|
||||||
import org.hl7.fhir.r5.model.TimeType;
|
import org.hl7.fhir.r5.model.TimeType;
|
||||||
import org.hl7.fhir.r5.model.TypeDetails;
|
import org.hl7.fhir.r5.model.TypeDetails;
|
||||||
import org.hl7.fhir.r5.model.TypeDetails.ProfiledType;
|
import org.hl7.fhir.r5.model.TypeDetails.ProfiledType;
|
||||||
|
import org.hl7.fhir.r5.terminologies.TerminologyServiceOptions;
|
||||||
import org.hl7.fhir.r5.model.ValueSet;
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
|
import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext.FunctionDetails;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext.FunctionDetails;
|
||||||
|
@ -175,6 +176,7 @@ public class FHIRPathEngine {
|
||||||
private Set<String> primitiveTypes = new HashSet<String>();
|
private Set<String> primitiveTypes = new HashSet<String>();
|
||||||
private Map<String, StructureDefinition> allTypes = new HashMap<String, StructureDefinition>();
|
private Map<String, StructureDefinition> allTypes = new HashMap<String, StructureDefinition>();
|
||||||
private boolean legacyMode; // some R2 and R3 constraints assume that != is valid for emptty sets, so when running for R2/R3, this is set ot true
|
private boolean legacyMode; // some R2 and R3 constraints assume that != is valid for emptty sets, so when running for R2/R3, this is set ot true
|
||||||
|
private TerminologyServiceOptions terminologyServiceOptions = new TerminologyServiceOptions();
|
||||||
|
|
||||||
// if the fhir path expressions are allowed to use constants beyond those defined in the specification
|
// if the fhir path expressions are allowed to use constants beyond those defined in the specification
|
||||||
// the application can implement them by providing a constant resolver
|
// the application can implement them by providing a constant resolver
|
||||||
|
@ -1893,13 +1895,13 @@ public class FHIRPathEngine {
|
||||||
if (vs != null) {
|
if (vs != null) {
|
||||||
for (Base l : left) {
|
for (Base l : left) {
|
||||||
if (l.fhirType().equals("code")) {
|
if (l.fhirType().equals("code")) {
|
||||||
if (worker.validateCode(l.castToCoding(l), vs).isOk())
|
if (worker.validateCode(terminologyServiceOptions , l.castToCoding(l), vs).isOk())
|
||||||
ans = true;
|
ans = true;
|
||||||
} else if (l.fhirType().equals("Coding")) {
|
} else if (l.fhirType().equals("Coding")) {
|
||||||
if (worker.validateCode(l.castToCoding(l), vs).isOk())
|
if (worker.validateCode(terminologyServiceOptions, l.castToCoding(l), vs).isOk())
|
||||||
ans = true;
|
ans = true;
|
||||||
} else if (l.fhirType().equals("CodeableConcept")) {
|
} else if (l.fhirType().equals("CodeableConcept")) {
|
||||||
if (worker.validateCode(l.castToCodeableConcept(l), vs).isOk())
|
if (worker.validateCode(terminologyServiceOptions, l.castToCodeableConcept(l), vs).isOk())
|
||||||
ans = true;
|
ans = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4306,5 +4308,10 @@ public class FHIRPathEngine {
|
||||||
private Equality boolToTriState(boolean b) {
|
private Equality boolToTriState(boolean b) {
|
||||||
return b ? Equality.True : Equality.False;
|
return b ? Equality.True : Equality.False;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public TerminologyServiceOptions getTerminologyServiceOptions() {
|
||||||
|
return terminologyServiceOptions;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,6 +133,9 @@ public interface IResourceValidator {
|
||||||
public boolean isErrorForUnknownProfiles();
|
public boolean isErrorForUnknownProfiles();
|
||||||
public void setErrorForUnknownProfiles(boolean errorForUnknownProfiles);
|
public void setErrorForUnknownProfiles(boolean errorForUnknownProfiles);
|
||||||
|
|
||||||
|
public String getValidationLanguage();
|
||||||
|
public void setValidationLanguage(String value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate suite
|
* Validate suite
|
||||||
*
|
*
|
||||||
|
|
|
@ -175,6 +175,7 @@ import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent;
|
||||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
||||||
|
import org.hl7.fhir.r5.terminologies.TerminologyServiceOptions;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
||||||
import org.hl7.fhir.r5.utils.LiquidEngine.LiquidDocument;
|
import org.hl7.fhir.r5.utils.LiquidEngine.LiquidDocument;
|
||||||
|
@ -999,6 +1000,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
||||||
private List<ConceptMapRenderInstructions> renderingMaps = new ArrayList<ConceptMapRenderInstructions>();
|
private List<ConceptMapRenderInstructions> renderingMaps = new ArrayList<ConceptMapRenderInstructions>();
|
||||||
private boolean pretty;
|
private boolean pretty;
|
||||||
private boolean canonicalUrlsAsLinks;
|
private boolean canonicalUrlsAsLinks;
|
||||||
|
private TerminologyServiceOptions terminologyServiceOptions = new TerminologyServiceOptions();
|
||||||
|
|
||||||
public NarrativeGenerator(String prefix, String basePath, IWorkerContext context) {
|
public NarrativeGenerator(String prefix, String basePath, IWorkerContext context) {
|
||||||
super();
|
super();
|
||||||
|
@ -1836,7 +1838,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String lookupCode(String system, String code) {
|
private String lookupCode(String system, String code) {
|
||||||
ValidationResult t = context.validateCode(system, code, null);
|
ValidationResult t = context.validateCode(terminologyServiceOptions , system, code, null);
|
||||||
|
|
||||||
if (t != null && t.getDisplay() != null)
|
if (t != null && t.getDisplay() != null)
|
||||||
return t.getDisplay();
|
return t.getDisplay();
|
||||||
|
@ -2568,7 +2570,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
||||||
private String getDisplayForConcept(String system, String value) {
|
private String getDisplayForConcept(String system, String value) {
|
||||||
if (value == null || system == null)
|
if (value == null || system == null)
|
||||||
return null;
|
return null;
|
||||||
ValidationResult cl = context.validateCode(system, value, null);
|
ValidationResult cl = context.validateCode(terminologyServiceOptions, system, value, null);
|
||||||
return cl == null ? null : cl.getDisplay();
|
return cl == null ? null : cl.getDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3765,7 +3767,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
||||||
li.ah(href).addText(f.getValue());
|
li.ah(href).addText(f.getValue());
|
||||||
} else if ("concept".equals(f.getProperty()) && inc.hasSystem()) {
|
} else if ("concept".equals(f.getProperty()) && inc.hasSystem()) {
|
||||||
li.addText(f.getValue());
|
li.addText(f.getValue());
|
||||||
ValidationResult vr = context.validateCode(inc.getSystem(), f.getValue(), null);
|
ValidationResult vr = context.validateCode(terminologyServiceOptions, inc.getSystem(), f.getValue(), null);
|
||||||
if (vr.isOk()) {
|
if (vr.isOk()) {
|
||||||
li.tx(" ("+vr.getDisplay()+")");
|
li.tx(" ("+vr.getDisplay()+")");
|
||||||
}
|
}
|
||||||
|
@ -3847,7 +3849,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return context.validateCode(inc.getSystem(), code, null).asConceptDefinition();
|
return context.validateCode(terminologyServiceOptions, inc.getSystem(), code, null).asConceptDefinition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4752,5 +4754,13 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TerminologyServiceOptions getTerminologyServiceOptions() {
|
||||||
|
return terminologyServiceOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTerminologyServiceOptions(TerminologyServiceOptions terminologyServiceOptions) {
|
||||||
|
this.terminologyServiceOptions = terminologyServiceOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,7 @@ import org.hl7.fhir.r5.model.TypeDetails.ProfiledType;
|
||||||
import org.hl7.fhir.r5.model.UriType;
|
import org.hl7.fhir.r5.model.UriType;
|
||||||
import org.hl7.fhir.r5.model.ValueSet;
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||||
|
import org.hl7.fhir.r5.terminologies.TerminologyServiceOptions;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||||
import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
|
import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
||||||
|
@ -221,7 +222,8 @@ public class StructureMapUtilities {
|
||||||
private FHIRPathEngine fpe;
|
private FHIRPathEngine fpe;
|
||||||
private ITransformerServices services;
|
private ITransformerServices services;
|
||||||
private ProfileKnowledgeProvider pkp;
|
private ProfileKnowledgeProvider pkp;
|
||||||
private Map<String, Integer> ids = new HashMap<String, Integer>();
|
private Map<String, Integer> ids = new HashMap<String, Integer>();
|
||||||
|
private TerminologyServiceOptions terminologyServiceOptions = new TerminologyServiceOptions();
|
||||||
|
|
||||||
public StructureMapUtilities(IWorkerContext worker, ITransformerServices services, ProfileKnowledgeProvider pkp) {
|
public StructureMapUtilities(IWorkerContext worker, ITransformerServices services, ProfileKnowledgeProvider pkp) {
|
||||||
super();
|
super();
|
||||||
|
@ -1965,7 +1967,7 @@ public class StructureMapUtilities {
|
||||||
throw new FHIRException("The code '"+code+"' is not in the value set '"+uri+"' (valid codes: "+b.toString()+"; also checked displays)");
|
throw new FHIRException("The code '"+code+"' is not in the value set '"+uri+"' (valid codes: "+b.toString()+"; also checked displays)");
|
||||||
} else
|
} else
|
||||||
system = uri;
|
system = uri;
|
||||||
ValidationResult vr = worker.validateCode(system, code, null);
|
ValidationResult vr = worker.validateCode(terminologyServiceOptions, system, code, null);
|
||||||
if (vr != null && vr.getDisplay() != null)
|
if (vr != null && vr.getDisplay() != null)
|
||||||
display = vr.getDisplay();
|
display = vr.getDisplay();
|
||||||
return new Coding().setSystem(system).setCode(code).setDisplay(display);
|
return new Coding().setSystem(system).setCode(code).setDisplay(display);
|
||||||
|
@ -2958,5 +2960,13 @@ public class StructureMapUtilities {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TerminologyServiceOptions getTerminologyServiceOptions() {
|
||||||
|
return terminologyServiceOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTerminologyServiceOptions(TerminologyServiceOptions terminologyServiceOptions) {
|
||||||
|
this.terminologyServiceOptions = terminologyServiceOptions;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.Stack;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.apache.commons.lang3.NotImplementedException;
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
|
@ -121,6 +122,7 @@ import org.hl7.fhir.r5.model.TypeDetails;
|
||||||
import org.hl7.fhir.r5.model.UriType;
|
import org.hl7.fhir.r5.model.UriType;
|
||||||
import org.hl7.fhir.r5.model.ValueSet;
|
import org.hl7.fhir.r5.model.ValueSet;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||||
|
import org.hl7.fhir.r5.terminologies.TerminologyServiceOptions;
|
||||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||||
import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
|
import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
|
||||||
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
||||||
|
@ -264,6 +266,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
private boolean noTerminologyChecks;
|
private boolean noTerminologyChecks;
|
||||||
private boolean hintAboutNonMustSupport;
|
private boolean hintAboutNonMustSupport;
|
||||||
private BestPracticeWarningLevel bpWarnings;
|
private BestPracticeWarningLevel bpWarnings;
|
||||||
|
private String validationLanguage;
|
||||||
|
|
||||||
private List<String> extensionDomains = new ArrayList<String>();
|
private List<String> extensionDomains = new ArrayList<String>();
|
||||||
|
|
||||||
|
@ -821,13 +824,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
|
|
||||||
// public API
|
// public API
|
||||||
private boolean checkCode(List<ValidationMessage> errors, Element element, String path, String code, String system, String display, boolean checkDisplay) throws TerminologyServiceException {
|
private boolean checkCode(List<ValidationMessage> errors, Element element, String path, String code, String system, String display, boolean checkDisplay, NodeStack stack) throws TerminologyServiceException {
|
||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
boolean ss = context.supportsSystem(system);
|
boolean ss = context.supportsSystem(system);
|
||||||
txTime = txTime + (System.nanoTime() - t);
|
txTime = txTime + (System.nanoTime() - t);
|
||||||
if (ss) {
|
if (ss) {
|
||||||
t = System.nanoTime();
|
t = System.nanoTime();
|
||||||
ValidationResult s = context.validateCode(system, code, checkDisplay ? display : null);
|
ValidationResult s = context.validateCode(new TerminologyServiceOptions(stack.workingLang), system, code, checkDisplay ? display : null);
|
||||||
txTime = txTime + (System.nanoTime() - t);
|
txTime = txTime + (System.nanoTime() - t);
|
||||||
if (s == null)
|
if (s == null)
|
||||||
return true;
|
return true;
|
||||||
|
@ -935,7 +938,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkCodeableConcept(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, ElementDefinition theElementCntext) {
|
private boolean checkCodeableConcept(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, ElementDefinition theElementCntext, NodeStack stack) {
|
||||||
boolean res = true;
|
boolean res = true;
|
||||||
if (!noTerminologyChecks && theElementCntext != null && theElementCntext.hasBinding()) {
|
if (!noTerminologyChecks && theElementCntext != null && theElementCntext.hasBinding()) {
|
||||||
ElementDefinitionBindingComponent binding = theElementCntext.getBinding();
|
ElementDefinitionBindingComponent binding = theElementCntext.getBinding();
|
||||||
|
@ -968,7 +971,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
if (!atLeastOneSystemIsSupported && binding.getStrength() == BindingStrength.EXAMPLE) {
|
if (!atLeastOneSystemIsSupported && binding.getStrength() == BindingStrength.EXAMPLE) {
|
||||||
// ignore this since we can't validate but it doesn't matter..
|
// ignore this since we can't validate but it doesn't matter..
|
||||||
} else {
|
} else {
|
||||||
ValidationResult vr = context.validateCode(cc, valueset);
|
ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), cc, valueset);
|
||||||
res = false;
|
res = false;
|
||||||
if (!vr.isOk()) {
|
if (!vr.isOk()) {
|
||||||
bindingsOk = false;
|
bindingsOk = false;
|
||||||
|
@ -977,7 +980,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "Could not confirm that the codes provided are in the value set " + describeReference(binding.getValueSet()) + " and a code from this value set is required (class = "+vr.getErrorClass().toString()+")");
|
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "Could not confirm that the codes provided are in the value set " + describeReference(binding.getValueSet()) + " and a code from this value set is required (class = "+vr.getErrorClass().toString()+")");
|
||||||
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
||||||
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
|
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
|
||||||
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), cc);
|
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), cc, stack);
|
||||||
else if (!noExtensibleWarnings)
|
else if (!noExtensibleWarnings)
|
||||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "Could not confirm that the codes provided are in the value set " + describeReference(binding.getValueSet()) + " and a code should come from this value set unless it has no suitable code (class = "+vr.getErrorClass().toString()+")");
|
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "Could not confirm that the codes provided are in the value set " + describeReference(binding.getValueSet()) + " and a code should come from this value set unless it has no suitable code (class = "+vr.getErrorClass().toString()+")");
|
||||||
} else if (binding.getStrength() == BindingStrength.PREFERRED)
|
} else if (binding.getStrength() == BindingStrength.PREFERRED)
|
||||||
|
@ -987,7 +990,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
txRule(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "None of the codes provided are in the value set " + describeReference(binding.getValueSet()) + " (" + valueset.getUrl()+", and a code from this value set is required) (codes = "+ccSummary(cc)+")");
|
txRule(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "None of the codes provided are in the value set " + describeReference(binding.getValueSet()) + " (" + valueset.getUrl()+", and a code from this value set is required) (codes = "+ccSummary(cc)+")");
|
||||||
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
||||||
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
|
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
|
||||||
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), cc);
|
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), cc, stack);
|
||||||
else if (!noExtensibleWarnings)
|
else if (!noExtensibleWarnings)
|
||||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "None of the codes provided are in the value set " + describeReference(binding.getValueSet()) + " (" + valueset.getUrl() + ", and a code should come from this value set unless it has no suitable code) (codes = "+ccSummary(cc)+")");
|
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "None of the codes provided are in the value set " + describeReference(binding.getValueSet()) + " (" + valueset.getUrl() + ", and a code should come from this value set unless it has no suitable code) (codes = "+ccSummary(cc)+")");
|
||||||
} else if (binding.getStrength() == BindingStrength.PREFERRED)
|
} else if (binding.getStrength() == BindingStrength.PREFERRED)
|
||||||
|
@ -1003,7 +1006,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
String nextCode = nextCoding.getCode();
|
String nextCode = nextCoding.getCode();
|
||||||
String nextSystem = nextCoding.getSystem();
|
String nextSystem = nextCoding.getSystem();
|
||||||
if (isNotBlank(nextCode) && isNotBlank(nextSystem) && context.supportsSystem(nextSystem)) {
|
if (isNotBlank(nextCode) && isNotBlank(nextSystem) && context.supportsSystem(nextSystem)) {
|
||||||
ValidationResult vr = context.validateCode(nextSystem, nextCode, null);
|
ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), nextSystem, nextCode, null);
|
||||||
if (!vr.isOk()) {
|
if (!vr.isOk()) {
|
||||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "Code {0} is not a valid code in code system {1}", nextCode, nextSystem);
|
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "Code {0} is not a valid code in code system {1}", nextCode, nextSystem);
|
||||||
}
|
}
|
||||||
|
@ -1027,13 +1030,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkMaxValueSet(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, String maxVSUrl, CodeableConcept cc) {
|
private void checkMaxValueSet(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, String maxVSUrl, CodeableConcept cc, NodeStack stack) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
ValueSet valueset = resolveBindingReference(profile, maxVSUrl, profile.getUrl());
|
ValueSet valueset = resolveBindingReference(profile, maxVSUrl, profile.getUrl());
|
||||||
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, "ValueSet " + describeReference(maxVSUrl) + " not found")) {
|
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, "ValueSet " + describeReference(maxVSUrl) + " not found")) {
|
||||||
try {
|
try {
|
||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
ValidationResult vr = context.validateCode(cc, valueset);
|
ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), cc, valueset);
|
||||||
txTime = txTime + (System.nanoTime() - t);
|
txTime = txTime + (System.nanoTime() - t);
|
||||||
if (!vr.isOk()) {
|
if (!vr.isOk()) {
|
||||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||||
|
@ -1047,13 +1050,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkMaxValueSet(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, String maxVSUrl, Coding c) {
|
private void checkMaxValueSet(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, String maxVSUrl, Coding c, NodeStack stack) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
ValueSet valueset = resolveBindingReference(profile, maxVSUrl, profile.getUrl());
|
ValueSet valueset = resolveBindingReference(profile, maxVSUrl, profile.getUrl());
|
||||||
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, "ValueSet " + describeReference(maxVSUrl) + " not found")) {
|
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, "ValueSet " + describeReference(maxVSUrl) + " not found")) {
|
||||||
try {
|
try {
|
||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
ValidationResult vr = context.validateCode(c, valueset);
|
ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), c, valueset);
|
||||||
txTime = txTime + (System.nanoTime() - t);
|
txTime = txTime + (System.nanoTime() - t);
|
||||||
if (!vr.isOk()) {
|
if (!vr.isOk()) {
|
||||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||||
|
@ -1067,13 +1070,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkMaxValueSet(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, String maxVSUrl, String value) {
|
private void checkMaxValueSet(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, String maxVSUrl, String value, NodeStack stack) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
ValueSet valueset = resolveBindingReference(profile, maxVSUrl, profile.getUrl());
|
ValueSet valueset = resolveBindingReference(profile, maxVSUrl, profile.getUrl());
|
||||||
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, "ValueSet " + describeReference(maxVSUrl) + " not found")) {
|
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, "ValueSet " + describeReference(maxVSUrl) + " not found")) {
|
||||||
try {
|
try {
|
||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
ValidationResult vr = context.validateCode(value, valueset);
|
ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), value, valueset);
|
||||||
txTime = txTime + (System.nanoTime() - t);
|
txTime = txTime + (System.nanoTime() - t);
|
||||||
if (!vr.isOk()) {
|
if (!vr.isOk()) {
|
||||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||||
|
@ -1101,7 +1104,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
checkFixedValue(errors, path + ".userSelected", focus.getNamedChild("userSelected"), fixed.getUserSelectedElement(), "userSelected", focus);
|
checkFixedValue(errors, path + ".userSelected", focus.getNamedChild("userSelected"), fixed.getUserSelectedElement(), "userSelected", focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkCoding(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, ElementDefinition theElementCntext, boolean inCodeableConcept, boolean checkDisplay) {
|
private void checkCoding(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, ElementDefinition theElementCntext, boolean inCodeableConcept, boolean checkDisplay, NodeStack stack) {
|
||||||
String code = element.getNamedChildValue("code");
|
String code = element.getNamedChildValue("code");
|
||||||
String system = element.getNamedChildValue("system");
|
String system = element.getNamedChildValue("system");
|
||||||
String display = element.getNamedChildValue("display");
|
String display = element.getNamedChildValue("display");
|
||||||
|
@ -1110,7 +1113,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
if (system != null && code != null && !noTerminologyChecks) {
|
if (system != null && code != null && !noTerminologyChecks) {
|
||||||
rule(errors, IssueType.CODEINVALID, element.line(), element.col(), path, !isValueSet(system), "The Coding references a value set, not a code system (\""+system+"\")");
|
rule(errors, IssueType.CODEINVALID, element.line(), element.col(), path, !isValueSet(system), "The Coding references a value set, not a code system (\""+system+"\")");
|
||||||
try {
|
try {
|
||||||
if (checkCode(errors, element, path, code, system, display, checkDisplay))
|
if (checkCode(errors, element, path, code, system, display, checkDisplay, stack))
|
||||||
if (theElementCntext != null && theElementCntext.hasBinding()) {
|
if (theElementCntext != null && theElementCntext.hasBinding()) {
|
||||||
ElementDefinitionBindingComponent binding = theElementCntext.getBinding();
|
ElementDefinitionBindingComponent binding = theElementCntext.getBinding();
|
||||||
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, binding != null, "Binding for " + path + " missing")) {
|
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, binding != null, "Binding for " + path + " missing")) {
|
||||||
|
@ -1122,7 +1125,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
ValidationResult vr = null;
|
ValidationResult vr = null;
|
||||||
if (binding.getStrength() != BindingStrength.EXAMPLE) {
|
if (binding.getStrength() != BindingStrength.EXAMPLE) {
|
||||||
vr = context.validateCode(c, valueset);
|
vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), c, valueset);
|
||||||
}
|
}
|
||||||
txTime = txTime + (System.nanoTime() - t);
|
txTime = txTime + (System.nanoTime() - t);
|
||||||
if (vr != null && !vr.isOk()) {
|
if (vr != null && !vr.isOk()) {
|
||||||
|
@ -1133,7 +1136,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "Could not confirm that the codes provided are in the value set " + describeReference(binding.getValueSet()) + " (" + valueset.getUrl()+", and a code from this value set is required)");
|
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "Could not confirm that the codes provided are in the value set " + describeReference(binding.getValueSet()) + " (" + valueset.getUrl()+", and a code from this value set is required)");
|
||||||
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
||||||
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
|
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
|
||||||
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), c);
|
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), c, stack);
|
||||||
else if (!noExtensibleWarnings)
|
else if (!noExtensibleWarnings)
|
||||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "Could not confirm that the codes provided are in the value set " + describeReference(binding.getValueSet()) + " (" + valueset.getUrl() + ", and a code should come from this value set unless it has no suitable code)");
|
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "Could not confirm that the codes provided are in the value set " + describeReference(binding.getValueSet()) + " (" + valueset.getUrl() + ", and a code should come from this value set unless it has no suitable code)");
|
||||||
} else if (binding.getStrength() == BindingStrength.PREFERRED)
|
} else if (binding.getStrength() == BindingStrength.PREFERRED)
|
||||||
|
@ -1142,7 +1145,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
txRule(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "The Coding provided is not in the value set " + describeReference(binding.getValueSet()) + " (" + valueset.getUrl() + ", and a code is required from this value set)"+(vr.getMessage() != null ? " (error message = "+vr.getMessage()+")" : ""));
|
txRule(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "The Coding provided is not in the value set " + describeReference(binding.getValueSet()) + " (" + valueset.getUrl() + ", and a code is required from this value set)"+(vr.getMessage() != null ? " (error message = "+vr.getMessage()+")" : ""));
|
||||||
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
||||||
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
|
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
|
||||||
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), c);
|
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), c, stack);
|
||||||
else
|
else
|
||||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "The Coding provided is not in the value set " + describeReference(binding.getValueSet()) + " (" + valueset.getUrl() + ", and a code should come from this value set unless it has no suitable code)"+(vr.getMessage() != null ? " (error message = "+vr.getMessage()+")" : ""));
|
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "The Coding provided is not in the value set " + describeReference(binding.getValueSet()) + " (" + valueset.getUrl() + ", and a code should come from this value set unless it has no suitable code)"+(vr.getMessage() != null ? " (error message = "+vr.getMessage()+")" : ""));
|
||||||
} else if (binding.getStrength() == BindingStrength.PREFERRED)
|
} else if (binding.getStrength() == BindingStrength.PREFERRED)
|
||||||
|
@ -1495,7 +1498,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
checkFixedValue(errors, path + ".end", focus.getNamedChild("end"), fixed.getEndElement(), "end", focus);
|
checkFixedValue(errors, path + ".end", focus.getNamedChild("end"), fixed.getEndElement(), "end", focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkPrimitive(Object appContext, List<ValidationMessage> errors, String path, String type, ElementDefinition context, Element e, StructureDefinition profile) throws FHIRException, IOException {
|
private void checkPrimitive(Object appContext, List<ValidationMessage> errors, String path, String type, ElementDefinition context, Element e, StructureDefinition profile, NodeStack node) throws FHIRException, IOException {
|
||||||
if (isBlank(e.primitiveValue())) {
|
if (isBlank(e.primitiveValue())) {
|
||||||
if (e.primitiveValue() == null)
|
if (e.primitiveValue() == null)
|
||||||
rule(errors, IssueType.INVALID, e.line(), e.col(), path, e.hasChildren(), "Primitive types must have a value or must have child extensions");
|
rule(errors, IssueType.INVALID, e.line(), e.col(), path, e.hasChildren(), "Primitive types must have a value or must have child extensions");
|
||||||
|
@ -1663,7 +1666,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.hasBinding() && e.primitiveValue() != null) {
|
if (context.hasBinding() && e.primitiveValue() != null) {
|
||||||
checkPrimitiveBinding(errors, path, type, context, e, profile);
|
checkPrimitiveBinding(errors, path, type, context, e, profile, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.equals("xhtml")) {
|
if (type.equals("xhtml")) {
|
||||||
|
@ -1730,7 +1733,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkPrimitiveBinding(List<ValidationMessage> errors, String path, String type, ElementDefinition elementContext, Element element, StructureDefinition profile) {
|
private void checkPrimitiveBinding(List<ValidationMessage> errors, String path, String type, ElementDefinition elementContext, Element element, StructureDefinition profile, NodeStack stack) {
|
||||||
// We ignore bindings that aren't on string, uri or code
|
// We ignore bindings that aren't on string, uri or code
|
||||||
if (!element.hasPrimitiveValue() || !("code".equals(type) || "string".equals(type) || "uri".equals(type) || "url".equals(type) || "canonical".equals(type))) {
|
if (!element.hasPrimitiveValue() || !("code".equals(type) || "string".equals(type) || "uri".equals(type) || "url".equals(type) || "canonical".equals(type))) {
|
||||||
return;
|
return;
|
||||||
|
@ -1749,7 +1752,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
ValidationResult vr = null;
|
ValidationResult vr = null;
|
||||||
if (binding.getStrength() != BindingStrength.EXAMPLE) {
|
if (binding.getStrength() != BindingStrength.EXAMPLE) {
|
||||||
vr = context.validateCode(value, vs);
|
vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), value, vs);
|
||||||
}
|
}
|
||||||
txTime = txTime + (System.nanoTime() - t);
|
txTime = txTime + (System.nanoTime() - t);
|
||||||
if (vr != null && !vr.isOk()) {
|
if (vr != null && !vr.isOk()) {
|
||||||
|
@ -1759,7 +1762,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
txRule(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "The value provided ('"+value+"') is not in the value set " + describeReference(binding.getValueSet()) + " (" + vs.getUrl() + ", and a code is required from this value set)"+(vr.getMessage() != null ? " (error message = "+vr.getMessage()+")" : ""));
|
txRule(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "The value provided ('"+value+"') is not in the value set " + describeReference(binding.getValueSet()) + " (" + vs.getUrl() + ", and a code is required from this value set)"+(vr.getMessage() != null ? " (error message = "+vr.getMessage()+")" : ""));
|
||||||
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
||||||
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
|
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
|
||||||
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), value);
|
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), value, stack);
|
||||||
else if (!noExtensibleWarnings)
|
else if (!noExtensibleWarnings)
|
||||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "The value provided ('"+value+"') is not in the value set " + describeReference(binding.getValueSet()) + " (" + vs.getUrl() + ", and a code should come from this value set unless it has no suitable code)"+(vr.getMessage() != null ? " (error message = "+vr.getMessage()+")" : ""));
|
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, "The value provided ('"+value+"') is not in the value set " + describeReference(binding.getValueSet()) + " (" + vs.getUrl() + ", and a code should come from this value set unless it has no suitable code)"+(vr.getMessage() != null ? " (error message = "+vr.getMessage()+")" : ""));
|
||||||
} else if (binding.getStrength() == BindingStrength.PREFERRED)
|
} else if (binding.getStrength() == BindingStrength.PREFERRED)
|
||||||
|
@ -2862,6 +2865,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
// the instance at root is valid against the schema and schematron
|
// the instance at root is valid against the schema and schematron
|
||||||
// the instance validator had no issues against the base resource profile
|
// the instance validator had no issues against the base resource profile
|
||||||
private void start(ValidatorHostContext hostContext, List<ValidationMessage> errors, Element resource, Element element, StructureDefinition defn, NodeStack stack) throws FHIRException, FHIRException, IOException {
|
private void start(ValidatorHostContext hostContext, List<ValidationMessage> errors, Element resource, Element element, StructureDefinition defn, NodeStack stack) throws FHIRException, FHIRException, IOException {
|
||||||
|
checkLang(resource, stack);
|
||||||
|
|
||||||
// profile is valid, and matches the resource name
|
// profile is valid, and matches the resource name
|
||||||
ResourceProfiles resourceProfiles = getResourceProfiles(element, stack);
|
ResourceProfiles resourceProfiles = getResourceProfiles(element, stack);
|
||||||
if (!resourceProfiles.isProcessed())
|
if (!resourceProfiles.isProcessed())
|
||||||
|
@ -2896,6 +2901,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkLang(Element resource, NodeStack stack) {
|
||||||
|
String lang = resource.getNamedChildValue("language");
|
||||||
|
if (!Utilities.noString(lang))
|
||||||
|
stack.workingLang = lang;
|
||||||
|
}
|
||||||
|
|
||||||
private void validateResourceRules(List<ValidationMessage> errors, Element element, NodeStack stack) {
|
private void validateResourceRules(List<ValidationMessage> errors, Element element, NodeStack stack) {
|
||||||
String lang = element.getNamedChildValue("language");
|
String lang = element.getNamedChildValue("language");
|
||||||
Element text = element.getNamedChild("text");
|
Element text = element.getNamedChild("text");
|
||||||
|
@ -3256,7 +3267,7 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L
|
||||||
}
|
}
|
||||||
|
|
||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
ValidationResult res = context.validateCode(c, vs);
|
ValidationResult res = context.validateCode(new TerminologyServiceOptions(stack.workingLang), c, vs);
|
||||||
txTime = txTime + (System.nanoTime() - t);
|
txTime = txTime + (System.nanoTime() - t);
|
||||||
if (!res.isOk()) {
|
if (!res.isOk()) {
|
||||||
txRule(errors, res.getTxLink(), IssueType.CODEINVALID, value.line(), value.col(), stack.getLiteralPath(), false, "The value provided (" + c.getSystem() + "::" + c.getCode() + ") is not in the options value set in the questionnaire");
|
txRule(errors, res.getTxLink(), IssueType.CODEINVALID, value.line(), value.col(), stack.getLiteralPath(), false, "The value provided (" + c.getSystem() + "::" + c.getCode() + ") is not in the options value set in the questionnaire");
|
||||||
|
@ -3968,7 +3979,7 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L
|
||||||
ei.element.markValidation(profile, ei.definition);
|
ei.element.markValidation(profile, ei.definition);
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
if (isPrimitiveType(type)) {
|
if (isPrimitiveType(type)) {
|
||||||
checkPrimitive(hostContext, errors, ei.path, type, ei.definition, ei.element, profile);
|
checkPrimitive(hostContext, errors, ei.path, type, ei.definition, ei.element, profile, stack);
|
||||||
} else {
|
} else {
|
||||||
if (ei.definition.hasFixed()) {
|
if (ei.definition.hasFixed()) {
|
||||||
checkFixedValue(errors,ei.path, ei.element, ei.definition.getFixed(), ei.definition.getSliceName(), null);
|
checkFixedValue(errors,ei.path, ei.element, ei.definition.getFixed(), ei.definition.getSliceName(), null);
|
||||||
|
@ -3980,9 +3991,9 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L
|
||||||
if (type.equals("Identifier")) {
|
if (type.equals("Identifier")) {
|
||||||
checkIdentifier(errors, ei.path, ei.element, ei.definition);
|
checkIdentifier(errors, ei.path, ei.element, ei.definition);
|
||||||
} else if (type.equals("Coding")) {
|
} else if (type.equals("Coding")) {
|
||||||
checkCoding(errors, ei.path, ei.element, profile, ei.definition, inCodeableConcept, checkDisplayInContext);
|
checkCoding(errors, ei.path, ei.element, profile, ei.definition, inCodeableConcept, checkDisplayInContext, stack);
|
||||||
} else if (type.equals("CodeableConcept")) {
|
} else if (type.equals("CodeableConcept")) {
|
||||||
checkDisplay = checkCodeableConcept(errors, ei.path, ei.element, profile, ei.definition);
|
checkDisplay = checkCodeableConcept(errors, ei.path, ei.element, profile, ei.definition, stack);
|
||||||
thisIsCodeableConcept = true;
|
thisIsCodeableConcept = true;
|
||||||
} else if (type.equals("Reference")) {
|
} else if (type.equals("Reference")) {
|
||||||
checkReference(hostContext, errors, ei.path, ei.element, profile, ei.definition, actualType, localStack);
|
checkReference(hostContext, errors, ei.path, ei.element, profile, ei.definition, actualType, localStack);
|
||||||
|
@ -4423,13 +4434,16 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L
|
||||||
private List<String> logicalPaths; // dotted format, various entry points
|
private List<String> logicalPaths; // dotted format, various entry points
|
||||||
private NodeStack parent;
|
private NodeStack parent;
|
||||||
private ElementDefinition type;
|
private ElementDefinition type;
|
||||||
|
private String workingLang;
|
||||||
|
|
||||||
public NodeStack() {
|
public NodeStack() {
|
||||||
|
workingLang = validationLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NodeStack(Element element) {
|
public NodeStack(Element element) {
|
||||||
this.element = element;
|
this.element = element;
|
||||||
literalPath = element.getName();
|
literalPath = element.getName();
|
||||||
|
workingLang = validationLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String addToLiteralPath(String... path) {
|
public String addToLiteralPath(String... path) {
|
||||||
|
@ -4471,6 +4485,7 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L
|
||||||
private NodeStack push(Element element, int count, ElementDefinition definition, ElementDefinition type) {
|
private NodeStack push(Element element, int count, ElementDefinition definition, ElementDefinition type) {
|
||||||
NodeStack res = new NodeStack();
|
NodeStack res = new NodeStack();
|
||||||
res.parent = this;
|
res.parent = this;
|
||||||
|
res.workingLang = this.workingLang;
|
||||||
res.element = element;
|
res.element = element;
|
||||||
res.definition = definition;
|
res.definition = definition;
|
||||||
res.literalPath = getLiteralPath() + "." + element.getName();
|
res.literalPath = getLiteralPath() + "." + element.getName();
|
||||||
|
@ -4632,5 +4647,13 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L
|
||||||
return externalHostServices;
|
return externalHostServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getValidationLanguage() {
|
||||||
|
return validationLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValidationLanguage(String validationLanguage) {
|
||||||
|
this.validationLanguage = validationLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,6 +244,7 @@ public class ValidationEngine {
|
||||||
private boolean hintAboutNonMustSupport;
|
private boolean hintAboutNonMustSupport;
|
||||||
private boolean anyExtensionsAllowed = false;
|
private boolean anyExtensionsAllowed = false;
|
||||||
private String version;
|
private String version;
|
||||||
|
private String language;
|
||||||
private PackageCacheManager pcm;
|
private PackageCacheManager pcm;
|
||||||
private PrintWriter mapLog;
|
private PrintWriter mapLog;
|
||||||
|
|
||||||
|
@ -323,6 +324,14 @@ public class ValidationEngine {
|
||||||
pcm = new PackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
pcm = new PackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getLanguage() {
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLanguage(String language) {
|
||||||
|
this.language = language;
|
||||||
|
}
|
||||||
|
|
||||||
private void loadDefinitions(String src) throws Exception {
|
private void loadDefinitions(String src) throws Exception {
|
||||||
Map<String, byte[]> source = loadIgSource(src);
|
Map<String, byte[]> source = loadIgSource(src);
|
||||||
if (version == null)
|
if (version == null)
|
||||||
|
@ -1062,6 +1071,7 @@ public class ValidationEngine {
|
||||||
validator.setHintAboutNonMustSupport(hintAboutNonMustSupport);
|
validator.setHintAboutNonMustSupport(hintAboutNonMustSupport);
|
||||||
validator.setAnyExtensionsAllowed(anyExtensionsAllowed);
|
validator.setAnyExtensionsAllowed(anyExtensionsAllowed);
|
||||||
validator.setNoInvariantChecks(isNoInvariantChecks());
|
validator.setNoInvariantChecks(isNoInvariantChecks());
|
||||||
|
validator.setValidationLanguage(language);
|
||||||
return validator;
|
return validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,6 +165,10 @@ public class Validator {
|
||||||
System.out.println(" * JSON: json.schema");
|
System.out.println(" * JSON: json.schema");
|
||||||
System.out.println(" * RDF: SHEX");
|
System.out.println(" * RDF: SHEX");
|
||||||
System.out.println(" Default: false");
|
System.out.println(" Default: false");
|
||||||
|
System.out.println("-language: [lang]");
|
||||||
|
System.out.println(" The language to use when validating coding displays - same value as for xml:lang");
|
||||||
|
System.out.println(" Not used if the resource specifies language");
|
||||||
|
System.out.println(" Default: no specified language");
|
||||||
System.out.println("-strictExtensions: If present, treat extensions not defined within the specified FHIR version and any");
|
System.out.println("-strictExtensions: If present, treat extensions not defined within the specified FHIR version and any");
|
||||||
System.out.println(" referenced implementation guides or profiles as errors. (Default is to only raise information messages.)");
|
System.out.println(" referenced implementation guides or profiles as errors. (Default is to only raise information messages.)");
|
||||||
System.out.println("-hintAboutNonMustSupport: If present, raise hints if the instance contains data elements that are not");
|
System.out.println("-hintAboutNonMustSupport: If present, raise hints if the instance contains data elements that are not");
|
||||||
|
@ -269,6 +273,7 @@ public class Validator {
|
||||||
String sv = null;
|
String sv = null;
|
||||||
String txLog = null;
|
String txLog = null;
|
||||||
String mapLog = null;
|
String mapLog = null;
|
||||||
|
String lang = null;
|
||||||
|
|
||||||
// load the parameters - so order doesn't matter
|
// load the parameters - so order doesn't matter
|
||||||
for (int i = 0; i < args.length; i++) {
|
for (int i = 0; i < args.length; i++) {
|
||||||
|
@ -337,6 +342,11 @@ public class Validator {
|
||||||
throw new Error("Specified -log without indicating file");
|
throw new Error("Specified -log without indicating file");
|
||||||
else
|
else
|
||||||
mapLog = args[++i];
|
mapLog = args[++i];
|
||||||
|
else if (args[i].equals("-language"))
|
||||||
|
if (i+1 == args.length)
|
||||||
|
throw new Error("Specified -language without indicating language");
|
||||||
|
else
|
||||||
|
lang = args[++i];
|
||||||
else if (args[i].equals("-ig"))
|
else if (args[i].equals("-ig"))
|
||||||
if (i+1 == args.length)
|
if (i+1 == args.length)
|
||||||
throw new Error("Specified -ig without indicating ig file");
|
throw new Error("Specified -ig without indicating ig file");
|
||||||
|
@ -378,6 +388,7 @@ public class Validator {
|
||||||
validator.setNative(doNative);
|
validator.setNative(doNative);
|
||||||
validator.setHintAboutNonMustSupport(hintAboutNonMustSupport);
|
validator.setHintAboutNonMustSupport(hintAboutNonMustSupport);
|
||||||
validator.setAnyExtensionsAllowed(anyExtensionsAllowed);
|
validator.setAnyExtensionsAllowed(anyExtensionsAllowed);
|
||||||
|
validator.setLanguage(lang);
|
||||||
|
|
||||||
IParser x;
|
IParser x;
|
||||||
if (output != null && output.endsWith(".json"))
|
if (output != null && output.endsWith(".json"))
|
||||||
|
|
|
@ -94,8 +94,8 @@ public class ValidationTestSuite implements IEvaluationContext, IValidatorResour
|
||||||
this.content = content;
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String DEF_TX = "http://tx.fhir.org";
|
// private static final String DEF_TX = "http://tx.fhir.org";
|
||||||
private static final String DBG_TX = "http://local.fhir.org:960";
|
private static final String DEF_TX = "http://local.fhir.org:960";
|
||||||
private static ValidationEngine ve;
|
private static ValidationEngine ve;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
|
@ -133,6 +133,10 @@ public class ValidationTestSuite implements IEvaluationContext, IValidatorResour
|
||||||
if (content.has("allowed-extension-domains"))
|
if (content.has("allowed-extension-domains"))
|
||||||
for (JsonElement a : content.getAsJsonArray("allowed-extension-domains"))
|
for (JsonElement a : content.getAsJsonArray("allowed-extension-domains"))
|
||||||
val.getExtensionDomains().add(a.getAsString());
|
val.getExtensionDomains().add(a.getAsString());
|
||||||
|
if (content.has("language"))
|
||||||
|
val.setValidationLanguage(content.get("language").getAsString());
|
||||||
|
else
|
||||||
|
val.setValidationLanguage(null);
|
||||||
val.setFetcher(this);
|
val.setFetcher(this);
|
||||||
if (content.has("questionnaire")) {
|
if (content.has("questionnaire")) {
|
||||||
ve.getContext().cacheResource(loadResource(TestUtilities.resourceNameToFile("validation-examples", content.get("questionnaire").getAsString()), v));
|
ve.getContext().cacheResource(loadResource(TestUtilities.resourceNameToFile("validation-examples", content.get("questionnaire").getAsString()), v));
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Observation xmlns="http://hl7.org/fhir">
|
||||||
|
<status value="final"/>
|
||||||
|
<code>
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="3151-8"/>
|
||||||
|
<display value="ingeademde O2" />
|
||||||
|
</coding>
|
||||||
|
</code>
|
||||||
|
<subject>
|
||||||
|
<reference value="Patient/example" />
|
||||||
|
<display value="Example Patient" />
|
||||||
|
</subject>
|
||||||
|
<effectiveDateTime value="2016-12-19T09:00:00Z" />
|
||||||
|
<valueQuantity>
|
||||||
|
<value value="8"/>
|
||||||
|
</valueQuantity>
|
||||||
|
</Observation>
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Observation xmlns="http://hl7.org/fhir">
|
||||||
|
<status value="final"/>
|
||||||
|
<code>
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="3151-8"/>
|
||||||
|
<display value="ingeademde O2" />
|
||||||
|
</coding>
|
||||||
|
</code>
|
||||||
|
<subject>
|
||||||
|
<reference value="Patient/example" />
|
||||||
|
<display value="Example Patient" />
|
||||||
|
</subject>
|
||||||
|
<effectiveDateTime value="2016-12-19T09:00:00Z" />
|
||||||
|
<valueQuantity>
|
||||||
|
<value value="8"/>
|
||||||
|
</valueQuantity>
|
||||||
|
</Observation>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Observation xmlns="http://hl7.org/fhir">
|
||||||
|
<language value="nl-NL"/>
|
||||||
|
<status value="final"/>
|
||||||
|
<code>
|
||||||
|
<coding>
|
||||||
|
<system value="http://loinc.org" />
|
||||||
|
<code value="3151-8"/>
|
||||||
|
<display value="ingeademde O2" />
|
||||||
|
</coding>
|
||||||
|
</code>
|
||||||
|
<subject>
|
||||||
|
<reference value="Patient/example" />
|
||||||
|
<display value="Example Patient" />
|
||||||
|
</subject>
|
||||||
|
<effectiveDateTime value="2016-12-19T09:00:00Z" />
|
||||||
|
<valueQuantity>
|
||||||
|
<value value="8"/>
|
||||||
|
</valueQuantity>
|
||||||
|
</Observation>
|
|
@ -176,7 +176,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"medication-atc.json": {
|
"medication-atc.json": {
|
||||||
"errorCount": 1,
|
"errorCount": 0,
|
||||||
"allowed-extension-domain": "https://api-v8-r4.hspconsortium.org/DrugFormulary0/open"
|
"allowed-extension-domain": "https://api-v8-r4.hspconsortium.org/DrugFormulary0/open"
|
||||||
},
|
},
|
||||||
"bp.json": {
|
"bp.json": {
|
||||||
|
@ -768,7 +768,20 @@
|
||||||
},
|
},
|
||||||
"bad-bundle-reference-type.xml": {
|
"bad-bundle-reference-type.xml": {
|
||||||
"errorCount": 1
|
"errorCount": 1
|
||||||
}
|
},
|
||||||
|
"loinc-lang-nl-1.xml" : {
|
||||||
|
"errorCount": 0,
|
||||||
|
"warningCount": 1
|
||||||
|
},
|
||||||
|
"loinc-lang-nl-2.xml" : {
|
||||||
|
"language" : "nl-NL",
|
||||||
|
"errorCount": 0,
|
||||||
|
"warningCount": 0
|
||||||
|
},
|
||||||
|
"loinc-lang-nl-3.xml" : {
|
||||||
|
"errorCount": 0,
|
||||||
|
"warningCount": 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue