refactor validation options, and improve codeableConcept validation, and improve code system rendering
This commit is contained in:
parent
64d4e7598d
commit
ea7f3a7957
|
@ -173,7 +173,7 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
|
|||
return new ValidationResult(cc);
|
||||
}
|
||||
}
|
||||
return new ValidationResult(IssueSeverity.WARNING, "Display Name for "+code.getSystem()+"#"+code.getCode()+" should be one of '"+b.toString()+"'", cc);
|
||||
return new ValidationResult(IssueSeverity.WARNING, "Display Name for "+code.getSystem()+"#"+code.getCode()+" should be one of '"+b.toString()+"' instead of "+code.getDisplay(), cc);
|
||||
}
|
||||
|
||||
private ConceptReferenceComponent findValueSetRef(String system, String code) {
|
||||
|
|
|
@ -95,6 +95,7 @@ import org.hl7.fhir.r5.utils.formats.XLSXWriter;
|
|||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.TerminologyServiceOptions;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
|
||||
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
|
||||
|
@ -254,7 +255,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
private ProfileKnowledgeProvider pkp;
|
||||
private boolean igmode;
|
||||
private boolean exception;
|
||||
private TerminologyServiceOptions terminologyServiceOptions = new TerminologyServiceOptions();
|
||||
private ValidationOptions terminologyServiceOptions = new ValidationOptions();
|
||||
private boolean newSlicingProcessing;
|
||||
private String defWebRoot;
|
||||
|
||||
|
@ -5161,12 +5162,12 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
|
||||
|
||||
public TerminologyServiceOptions getTerminologyServiceOptions() {
|
||||
public ValidationOptions getTerminologyServiceOptions() {
|
||||
return terminologyServiceOptions;
|
||||
}
|
||||
|
||||
|
||||
public void setTerminologyServiceOptions(TerminologyServiceOptions terminologyServiceOptions) {
|
||||
public void setTerminologyServiceOptions(ValidationOptions terminologyServiceOptions) {
|
||||
this.terminologyServiceOptions = terminologyServiceOptions;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -83,6 +84,7 @@ import org.hl7.fhir.utilities.TerminologyServiceOptions;
|
|||
import org.hl7.fhir.utilities.TranslationServices;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
||||
|
||||
|
@ -512,38 +514,25 @@ public abstract class BaseWorkerContext implements IWorkerContext {
|
|||
// --- validate code -------------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public ValidationResult validateCode(TerminologyServiceOptions options, String system, String code, String display) {
|
||||
public ValidationResult validateCode(ValidationOptions options, String system, String code, String display) {
|
||||
Coding c = new Coding(system, code, display);
|
||||
return validateCode(options, c, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationResult validateCode(TerminologyServiceOptions options, String system, String code, String display, ValueSet vs) {
|
||||
public ValidationResult validateCode(ValidationOptions options, String system, String code, String display, ValueSet vs) {
|
||||
Coding c = new Coding(system, code, display);
|
||||
return validateCode(options, c, vs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationResult validateCode(TerminologyServiceOptions options, String code, ValueSet vs) {
|
||||
public ValidationResult validateCode(ValidationOptions options, String code, ValueSet vs) {
|
||||
Coding c = new Coding(null, code, null);
|
||||
return doValidateCode(options, c, vs, true);
|
||||
return validateCode(options.guessSystem(), c, vs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationResult validateCode(TerminologyServiceOptions options, String system, String code, String display, ConceptSetComponent vsi) {
|
||||
Coding c = new Coding(system, code, display);
|
||||
ValueSet vs = new ValueSet();
|
||||
vs.setUrl(Utilities.makeUuidUrn());
|
||||
vs.getCompose().addInclude(vsi);
|
||||
return validateCode(options, c, vs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationResult validateCode(TerminologyServiceOptions options, Coding code, ValueSet vs) {
|
||||
return doValidateCode(options, code, vs, false);
|
||||
}
|
||||
|
||||
public ValidationResult doValidateCode(TerminologyServiceOptions options, Coding code, ValueSet vs, boolean implySystem) {
|
||||
public ValidationResult validateCode(ValidationOptions options, Coding code, ValueSet vs) {
|
||||
CacheToken cacheToken = txCache != null ? txCache.generateValidationToken(options, code, vs) : null;
|
||||
ValidationResult res = null;
|
||||
if (txCache != null)
|
||||
|
@ -551,31 +540,38 @@ public abstract class BaseWorkerContext implements IWorkerContext {
|
|||
if (res != null)
|
||||
return res;
|
||||
|
||||
// ok, first we try to validate locally
|
||||
try {
|
||||
ValueSetCheckerSimple vsc = new ValueSetCheckerSimple(options, vs, this);
|
||||
res = vsc.validateCode(code);
|
||||
if (txCache != null)
|
||||
txCache.cacheValidation(cacheToken, res, TerminologyCache.TRANSIENT);
|
||||
return res;
|
||||
} catch (Exception e) {
|
||||
if (options.isUseClient()) {
|
||||
// ok, first we try to validate locally
|
||||
try {
|
||||
ValueSetCheckerSimple vsc = new ValueSetCheckerSimple(options, vs, this);
|
||||
res = vsc.validateCode(code);
|
||||
if (txCache != null)
|
||||
txCache.cacheValidation(cacheToken, res, TerminologyCache.TRANSIENT);
|
||||
return res;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.isUseServer()) {
|
||||
return new ValidationResult(IssueSeverity.WARNING, "Unable to validate code without using server", TerminologyServiceErrorClass.BLOCKED_BY_OPTIONS);
|
||||
}
|
||||
|
||||
// if that failed, we try to validate on the server
|
||||
if (noTerminologyServer)
|
||||
if (noTerminologyServer) {
|
||||
return new ValidationResult(IssueSeverity.ERROR, "Error validating code: running without terminology services", TerminologyServiceErrorClass.NOSERVICE);
|
||||
}
|
||||
String csumm = txCache != null ? txCache.summary(code) : null;
|
||||
if (txCache != null)
|
||||
if (txCache != null) {
|
||||
tlog("$validate "+csumm+" for "+ txCache.summary(vs));
|
||||
else
|
||||
} else {
|
||||
tlog("$validate "+csumm+" before cache exists");
|
||||
}
|
||||
try {
|
||||
Parameters pIn = new Parameters();
|
||||
pIn.addParameter().setName("coding").setValue(code);
|
||||
if (implySystem)
|
||||
if (options.isGuessSystem())
|
||||
pIn.addParameter().setName("implySystem").setValue(new BooleanType(true));
|
||||
if (options != null)
|
||||
setTerminologyOptions(options, pIn);
|
||||
setTerminologyOptions(options, pIn);
|
||||
res = validateOnServer(vs, pIn);
|
||||
} catch (Exception e) {
|
||||
res = new ValidationResult(IssueSeverity.ERROR, e.getMessage() == null ? e.getClass().getName() : e.getMessage()).setTxLink(txLog == null ? null : txLog.getLastId());
|
||||
|
@ -585,29 +581,33 @@ public abstract class BaseWorkerContext implements IWorkerContext {
|
|||
return res;
|
||||
}
|
||||
|
||||
private void setTerminologyOptions(TerminologyServiceOptions options, Parameters pIn) {
|
||||
if (options != null) {
|
||||
if (!Utilities.noString(options.getLanguage()))
|
||||
pIn.addParameter("displayLanguage", options.getLanguage());
|
||||
}
|
||||
private void setTerminologyOptions(ValidationOptions options, Parameters pIn) {
|
||||
if (!Utilities.noString(options.getLanguage()))
|
||||
pIn.addParameter("displayLanguage", options.getLanguage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationResult validateCode(TerminologyServiceOptions options, CodeableConcept code, ValueSet vs) {
|
||||
public ValidationResult validateCode(ValidationOptions options, CodeableConcept code, ValueSet vs) {
|
||||
CacheToken cacheToken = txCache.generateValidationToken(options, code, vs);
|
||||
ValidationResult res = txCache.getValidation(cacheToken);
|
||||
if (res != null)
|
||||
return res;
|
||||
|
||||
// ok, first we try to validate locally
|
||||
try {
|
||||
ValueSetCheckerSimple vsc = new ValueSetCheckerSimple(options, vs, this);
|
||||
res = vsc.validateCode(code);
|
||||
txCache.cacheValidation(cacheToken, res, TerminologyCache.TRANSIENT);
|
||||
return res;
|
||||
} catch (Exception e) {
|
||||
if (options.isUseClient()) {
|
||||
// ok, first we try to validate locally
|
||||
try {
|
||||
ValueSetCheckerSimple vsc = new ValueSetCheckerSimple(options, vs, this);
|
||||
res = vsc.validateCode(code);
|
||||
txCache.cacheValidation(cacheToken, res, TerminologyCache.TRANSIENT);
|
||||
return res;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.isUseServer()) {
|
||||
return new ValidationResult(IssueSeverity.WARNING, "Unable to validate code without using server", TerminologyServiceErrorClass.BLOCKED_BY_OPTIONS);
|
||||
}
|
||||
|
||||
// if that failed, we try to validate on the server
|
||||
if (noTerminologyServer)
|
||||
return new ValidationResult(IssueSeverity.ERROR, "Error validating code: running without terminology services", TerminologyServiceErrorClass.NOSERVICE);
|
||||
|
@ -615,8 +615,7 @@ public abstract class BaseWorkerContext implements IWorkerContext {
|
|||
try {
|
||||
Parameters pIn = new Parameters();
|
||||
pIn.addParameter().setName("codeableConcept").setValue(code);
|
||||
if (options != null)
|
||||
setTerminologyOptions(options, pIn);
|
||||
setTerminologyOptions(options, pIn);
|
||||
res = validateOnServer(vs, pIn);
|
||||
} catch (Exception e) {
|
||||
res = new ValidationResult(IssueSeverity.ERROR, e.getMessage() == null ? e.getClass().getName() : e.getMessage()).setTxLink(txLog.getLastId());
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package org.hl7.fhir.r5.context;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
/*-
|
||||
* #%L
|
||||
* org.hl7.fhir.r5
|
||||
|
@ -50,6 +52,7 @@ import org.hl7.fhir.r5.utils.INarrativeGenerator;
|
|||
import org.hl7.fhir.r5.utils.IResourceValidator;
|
||||
import org.hl7.fhir.utilities.TerminologyServiceOptions;
|
||||
import org.hl7.fhir.utilities.TranslationServices;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
|
||||
|
||||
|
@ -209,17 +212,57 @@ public interface IWorkerContext {
|
|||
|
||||
// -- profile services ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @return a list of the resource names defined for this version
|
||||
*/
|
||||
public List<String> getResourceNames();
|
||||
/**
|
||||
* @return a set of the resource names defined for this version
|
||||
*/
|
||||
public Set<String> getResourceNamesAsSet();
|
||||
|
||||
/**
|
||||
* @return a list of the resource and type names defined for this version
|
||||
*/
|
||||
public List<String> getTypeNames();
|
||||
public List<StructureDefinition> allStructures(); // ensure snapshot exists...
|
||||
|
||||
/**
|
||||
* @return a list of all structure definitions, with snapshots generated (if possible)
|
||||
*/
|
||||
public List<StructureDefinition> allStructures();
|
||||
|
||||
/**
|
||||
* @return a list of all structure definitions, without trying to generate snapshots
|
||||
*/
|
||||
public List<StructureDefinition> getStructures();
|
||||
|
||||
/**
|
||||
* @return a list of all conformance resources
|
||||
*/
|
||||
public List<MetadataResource> allConformanceResources();
|
||||
|
||||
/**
|
||||
* Given a structure definition, generate a snapshot (or regenerate it)
|
||||
* @param p
|
||||
* @throws DefinitionException
|
||||
* @throws FHIRException
|
||||
*/
|
||||
public void generateSnapshot(StructureDefinition p) throws DefinitionException, FHIRException;
|
||||
|
||||
// -- Terminology services ------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set the expansion parameters passed through the terminology server when txServer calls are made
|
||||
*
|
||||
* Note that the Validation Options override these when they are specified on validateCode
|
||||
*/
|
||||
public Parameters getExpansionParameters();
|
||||
|
||||
/**
|
||||
* Get the expansion parameters passed through the terminology server when txServer calls are made
|
||||
*
|
||||
* Note that the Validation Options override these when they are specified on validateCode
|
||||
*/
|
||||
public void setExpansionProfile(Parameters expParameters);
|
||||
|
||||
// these are the terminology services used internally by the tools
|
||||
|
@ -272,6 +315,7 @@ public interface IWorkerContext {
|
|||
* @throws FHIRException
|
||||
*/
|
||||
public ValueSetExpansionOutcome expandVS(ElementDefinitionBindingComponent binding, boolean cacheOk, boolean heiarchical) throws FHIRException;
|
||||
|
||||
/**
|
||||
* Value set expanion inside the internal expansion engine - used
|
||||
* for references to supported system (see "supportsSystem") for
|
||||
|
@ -364,68 +408,108 @@ public interface IWorkerContext {
|
|||
}
|
||||
|
||||
/**
|
||||
* Validation of a code - consult the terminology service
|
||||
* Validation of a code - consult the terminology infrstructure and/or service
|
||||
* to see whether it is known. If known, return a description of it
|
||||
*
|
||||
* note: always return a result, with either an error or a code description
|
||||
* note: always return a result, with either an error or a code description
|
||||
*
|
||||
* corresponds to 2 terminology service calls: $validate-code and $lookup
|
||||
*
|
||||
* @param system
|
||||
* @param code
|
||||
* @param display
|
||||
* in this case, the system will be inferred from the value set. It's an error to call this one without the value set
|
||||
*
|
||||
* @param options - validation options (required)
|
||||
* @param code he code to validate (required)
|
||||
* @param vs the applicable valueset (required)
|
||||
* @return
|
||||
*/
|
||||
public ValidationResult validateCode(TerminologyServiceOptions options, String system, String code, String display);
|
||||
|
||||
/**
|
||||
* Validation of a code - consult the terminology service
|
||||
* to see whether it is known. If known, return a description of it
|
||||
* Also, check whether it's in the provided value set
|
||||
*
|
||||
* note: always return a result, with either an error or a code description, or both (e.g. known code, but not in the value set)
|
||||
*
|
||||
* corresponds to 2 terminology service calls: $validate-code and $lookup
|
||||
*
|
||||
* @param system
|
||||
* @param code
|
||||
* @param display
|
||||
* @return
|
||||
*/
|
||||
public ValidationResult validateCode(TerminologyServiceOptions options, String system, String code, String display, ValueSet vs);
|
||||
public ValidationResult validateCode(TerminologyServiceOptions options, String code, ValueSet vs);
|
||||
public ValidationResult validateCode(TerminologyServiceOptions options, Coding code, ValueSet vs);
|
||||
public ValidationResult validateCode(TerminologyServiceOptions options, CodeableConcept code, ValueSet vs);
|
||||
public ValidationResult validateCode(ValidationOptions options, String code, ValueSet vs);
|
||||
|
||||
/**
|
||||
* Validation of a code - consult the terminology service
|
||||
* Validation of a code - consult the terminology infrstructure and/or service
|
||||
* to see whether it is known. If known, return a description of it
|
||||
* Also, check whether it's in the provided value set fragment (for supported systems with no value set definition)
|
||||
*
|
||||
* note: always return a result, with either an error or a code description, or both (e.g. known code, but not in the value set)
|
||||
* note: always return a result, with either an error or a code description
|
||||
*
|
||||
* corresponds to 2 terminology service calls: $validate-code and $lookup
|
||||
*
|
||||
* @param system
|
||||
* @param code
|
||||
* @param display
|
||||
* @param options - validation options (required)
|
||||
* @param system - equals Coding.system (required)
|
||||
* @param code - equals Coding.code (required)
|
||||
* @param display - equals Coding.display (optional)
|
||||
* @return
|
||||
*/
|
||||
public ValidationResult validateCode(TerminologyServiceOptions options, String system, String code, String display, ConceptSetComponent vsi);
|
||||
public ValidationResult validateCode(ValidationOptions options, String system, String code, String display);
|
||||
|
||||
/**
|
||||
* Validation of a code - consult the terminology infrstructure and/or service
|
||||
* to see whether it is known. If known, return a description of it
|
||||
*
|
||||
* note: always return a result, with either an error or a code description
|
||||
*
|
||||
* corresponds to 2 terminology service calls: $validate-code and $lookup
|
||||
*
|
||||
* @param options - validation options (required)
|
||||
* @param system - equals Coding.system (required)
|
||||
* @param code - equals Coding.code (required)
|
||||
* @param display - equals Coding.display (optional)
|
||||
* @param vs the applicable valueset (optional)
|
||||
* @return
|
||||
*/
|
||||
public ValidationResult validateCode(ValidationOptions options, String system, String code, String display, ValueSet vs);
|
||||
|
||||
/**
|
||||
* returns the recommended tla for the type
|
||||
* Validation of a code - consult the terminology infrstructure and/or service
|
||||
* to see whether it is known. If known, return a description of it
|
||||
*
|
||||
* note: always return a result, with either an error or a code description
|
||||
*
|
||||
* corresponds to 2 terminology service calls: $validate-code and $lookup
|
||||
*
|
||||
* Note that this doesn't validate binding strength (e.g. is just text allowed?)
|
||||
*
|
||||
* @param options - validation options (required)
|
||||
* @param code - CodeableConcept to validate
|
||||
* @param vs the applicable valueset (optional)
|
||||
* @return
|
||||
*/
|
||||
public ValidationResult validateCode(ValidationOptions options, CodeableConcept code, ValueSet vs);
|
||||
|
||||
/**
|
||||
* Validation of a code - consult the terminology infrstructure and/or service
|
||||
* to see whether it is known. If known, return a description of it
|
||||
*
|
||||
* note: always return a result, with either an error or a code description
|
||||
*
|
||||
* corresponds to 2 terminology service calls: $validate-code and $lookup
|
||||
*
|
||||
* in this case, the system will be inferred from the value set. It's an error to call this one without the value set
|
||||
*
|
||||
* @param options - validation options (required)
|
||||
* @param code - Coding to validate
|
||||
* @param vs the applicable valueset (optional)
|
||||
* @return
|
||||
*/
|
||||
public ValidationResult validateCode(ValidationOptions options, Coding code, ValueSet vs);
|
||||
|
||||
/**
|
||||
* returns the recommended tla for the type (from the structure definitions)
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public String getAbbreviation(String name);
|
||||
|
||||
// return a set of types that have tails
|
||||
public Set<String> typeTails();
|
||||
|
||||
/**
|
||||
* translate an OID to a URI (look through known NamingSystems)
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
public String oid2Uri(String code);
|
||||
|
||||
/**
|
||||
* @return true if the contxt has a terminology caching service internally
|
||||
*/
|
||||
public boolean hasCache();
|
||||
|
||||
public interface ILoggingService {
|
||||
|
@ -458,4 +542,5 @@ public interface IWorkerContext {
|
|||
public void setUcumService(UcumService ucumService);
|
||||
|
||||
public String getLinkForUrl(String corePath, String s);
|
||||
|
||||
}
|
||||
|
|
|
@ -464,11 +464,6 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
this.questionnaire = questionnaire;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> typeTails() {
|
||||
return new HashSet<String>(Arrays.asList("Integer","Integer64","UnsignedInt","PositiveInt","Decimal","DateTime","Date","Time","Instant","String","Uri","Url","Canonical","Oid","Uuid","Id","Boolean","Code","Markdown","Base64Binary","Coding","CodeableConcept","Attachment","Identifier","Quantity","SampledData","Range","Period","Ratio","HumanName","Address","ContactPoint","Timing","Reference","Annotation","Signature","Meta"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StructureDefinition> allStructures() {
|
||||
List<StructureDefinition> result = new ArrayList<StructureDefinition>();
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.io.FileOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -46,9 +47,9 @@ import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
|||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.TerminologyServiceOptions;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
@ -112,7 +113,7 @@ public class TerminologyCache {
|
|||
load();
|
||||
}
|
||||
|
||||
public CacheToken generateValidationToken(TerminologyServiceOptions options, Coding code, ValueSet vs) {
|
||||
public CacheToken generateValidationToken(ValidationOptions options, Coding code, ValueSet vs) {
|
||||
CacheToken ct = new CacheToken();
|
||||
if (code.hasSystem())
|
||||
ct.name = getNameForSystem(code.getSystem());
|
||||
|
@ -130,7 +131,7 @@ public class TerminologyCache {
|
|||
return ct;
|
||||
}
|
||||
|
||||
public CacheToken generateValidationToken(TerminologyServiceOptions options, CodeableConcept code, ValueSet vs) {
|
||||
public CacheToken generateValidationToken(ValidationOptions options, CodeableConcept code, ValueSet vs) {
|
||||
CacheToken ct = new CacheToken();
|
||||
for (Coding c : code.getCoding()) {
|
||||
if (c.hasSystem())
|
||||
|
|
|
@ -88,7 +88,6 @@ public class CodeSystemUtilities {
|
|||
processed.add(cd.getCode());
|
||||
}
|
||||
}
|
||||
System.out.println("children of (root): "+res);
|
||||
return res;
|
||||
} else {
|
||||
return cs.getConcept();
|
||||
|
@ -106,7 +105,6 @@ public class CodeSystemUtilities {
|
|||
processed.add(cd.getCode());
|
||||
}
|
||||
}
|
||||
System.out.println("children of "+context+": "+res);
|
||||
return res;
|
||||
} else {
|
||||
return context.getConcept();
|
||||
|
@ -131,7 +129,6 @@ public class CodeSystemUtilities {
|
|||
res.add(cd);
|
||||
}
|
||||
}
|
||||
System.out.println("non-children of "+context+": "+res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.hl7.fhir.r5.terminologies;
|
|||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -45,6 +46,8 @@ import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent;
|
|||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.TerminologyServiceOptions;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
|
||||
public class ValueSetCheckerSimple implements ValueSetChecker {
|
||||
|
@ -52,9 +55,9 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
|
|||
private ValueSet valueset;
|
||||
private IWorkerContext context;
|
||||
private Map<String, ValueSetCheckerSimple> inner = new HashMap<>();
|
||||
private TerminologyServiceOptions options;
|
||||
private ValidationOptions options;
|
||||
|
||||
public ValueSetCheckerSimple(TerminologyServiceOptions options, ValueSet source, IWorkerContext context) {
|
||||
public ValueSetCheckerSimple(ValidationOptions options, ValueSet source, IWorkerContext context) {
|
||||
this.valueset = source;
|
||||
this.context = context;
|
||||
this.options = options;
|
||||
|
@ -66,19 +69,18 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
|
|||
List<String> warnings = new ArrayList<String>();
|
||||
for (Coding c : code.getCoding()) {
|
||||
if (!c.hasSystem())
|
||||
warnings.add("Coding has no system");
|
||||
warnings.add("Coding has no system - cannot validate");
|
||||
CodeSystem cs = context.fetchCodeSystem(c.getSystem());
|
||||
if (cs == null)
|
||||
warnings.add("Unsupported system "+c.getSystem()+" - system is not specified or implicit");
|
||||
else if (cs.getContent() != CodeSystemContentMode.COMPLETE)
|
||||
warnings.add("Unable to resolve system "+c.getSystem()+" - system is not complete");
|
||||
else {
|
||||
ValidationResult res = validateCode(c, cs);
|
||||
if (!res.isOk())
|
||||
errors.add(res.getMessage());
|
||||
else if (res.getMessage() != null)
|
||||
warnings.add(res.getMessage());
|
||||
ValidationResult res = null;
|
||||
if (cs == null || cs.getContent() != CodeSystemContentMode.COMPLETE) {
|
||||
res = context.validateCode(options.noClient(), c, null);
|
||||
} else {
|
||||
res = validateCode(c, cs);
|
||||
}
|
||||
if (!res.isOk())
|
||||
errors.add(res.getMessage());
|
||||
else if (res.getMessage() != null)
|
||||
warnings.add(res.getMessage());
|
||||
}
|
||||
if (valueset != null) {
|
||||
boolean ok = false;
|
||||
|
@ -182,7 +184,7 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
|
|||
return new ValidationResult(cc);
|
||||
}
|
||||
}
|
||||
return new ValidationResult(IssueSeverity.WARNING, "Display Name for "+code.getSystem()+"#"+code.getCode()+" should be one of '"+b.toString()+"'", cc);
|
||||
return new ValidationResult(IssueSeverity.WARNING, "Display Name for "+code.getSystem()+"#"+code.getCode()+" should be one of '"+b.toString()+"' instead of '"+code.getDisplay()+"'", cc);
|
||||
}
|
||||
|
||||
private ConceptReferenceComponent findValueSetRef(String system, String code) {
|
||||
|
@ -346,36 +348,40 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
|
|||
|
||||
if (!system.equals(vsi.getSystem()))
|
||||
return false;
|
||||
if (vsi.hasFilter()) {
|
||||
boolean ok = true;
|
||||
for (ConceptSetFilterComponent f : vsi.getFilter())
|
||||
if (!codeInFilter(system, f, code)) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
if (ok)
|
||||
return true;
|
||||
}
|
||||
|
||||
CodeSystem def = context.fetchCodeSystem(system);
|
||||
if (def.getContent() != CodeSystemContentMode.COMPLETE)
|
||||
throw new FHIRException("Unable to resolve system "+vsi.getSystem()+" - system is not complete");
|
||||
|
||||
List<ConceptDefinitionComponent> list = def.getConcept();
|
||||
boolean ok = validateCodeInConceptList(code, def, list);
|
||||
if (ok && vsi.hasConcept()) {
|
||||
for (ConceptReferenceComponent cc : vsi.getConcept())
|
||||
if (cc.getCode().equals(code))
|
||||
// ok, we need the code system
|
||||
CodeSystem cs = context.fetchCodeSystem(system);
|
||||
if (cs == null || cs.getContent() != CodeSystemContentMode.COMPLETE) {
|
||||
// make up a transient value set with
|
||||
ValueSet vs = new ValueSet();
|
||||
vs.setUrl(Utilities.makeUuidUrn());
|
||||
vs.getCompose().addInclude(vsi);
|
||||
ValidationResult res = context.validateCode(options.noClient(), new Coding(system, code, null), vs);
|
||||
return res.isOk();
|
||||
} else {
|
||||
if (vsi.hasFilter()) {
|
||||
boolean ok = true;
|
||||
for (ConceptSetFilterComponent f : vsi.getFilter())
|
||||
if (!codeInFilter(cs, system, f, code)) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
if (ok)
|
||||
return true;
|
||||
return false;
|
||||
} else
|
||||
return ok;
|
||||
}
|
||||
|
||||
List<ConceptDefinitionComponent> list = cs.getConcept();
|
||||
boolean ok = validateCodeInConceptList(code, cs, list);
|
||||
if (ok && vsi.hasConcept()) {
|
||||
for (ConceptReferenceComponent cc : vsi.getConcept())
|
||||
if (cc.getCode().equals(code))
|
||||
return true;
|
||||
return false;
|
||||
} else
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean codeInFilter(String system, ConceptSetFilterComponent f, String code) throws FHIRException {
|
||||
CodeSystem cs = context.fetchCodeSystem(system);
|
||||
if (cs == null)
|
||||
throw new FHIRException("Unable to evaluate filters on unknown code system '"+system+"'");
|
||||
private boolean codeInFilter(CodeSystem cs, String system, ConceptSetFilterComponent f, String code) throws FHIRException {
|
||||
if ("concept".equals(f.getProperty()))
|
||||
return codeInConceptFilter(cs, f, code);
|
||||
else {
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.hl7.fhir.r5.model.ValueSet;
|
|||
|
||||
public interface ValueSetExpander {
|
||||
public enum TerminologyServiceErrorClass {
|
||||
UNKNOWN, NOSERVICE, SERVER_ERROR, VALUESET_UNSUPPORTED;
|
||||
UNKNOWN, NOSERVICE, SERVER_ERROR, VALUESET_UNSUPPORTED, BLOCKED_BY_OPTIONS;
|
||||
|
||||
public boolean isInfrastructure() {
|
||||
return this == NOSERVICE || this == SERVER_ERROR || this == VALUESET_UNSUPPORTED;
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
|
|||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext.FunctionDetails;
|
||||
import org.hl7.fhir.utilities.TerminologyServiceOptions;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
|
@ -153,7 +154,7 @@ public class FHIRPathEngine {
|
|||
private Set<String> primitiveTypes = new HashSet<String>();
|
||||
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 TerminologyServiceOptions terminologyServiceOptions = new TerminologyServiceOptions();
|
||||
private ValidationOptions terminologyServiceOptions = new ValidationOptions();
|
||||
|
||||
// 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
|
||||
|
@ -4353,7 +4354,7 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
|
||||
public TerminologyServiceOptions getTerminologyServiceOptions() {
|
||||
public ValidationOptions getTerminologyServiceOptions() {
|
||||
return terminologyServiceOptions;
|
||||
}
|
||||
|
||||
|
|
|
@ -187,6 +187,7 @@ import org.hl7.fhir.utilities.MarkDownProcessor;
|
|||
import org.hl7.fhir.utilities.TerminologyServiceOptions;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor.Dialect;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
@ -1006,7 +1007,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
private List<ConceptMapRenderInstructions> renderingMaps = new ArrayList<ConceptMapRenderInstructions>();
|
||||
private boolean pretty;
|
||||
private boolean canonicalUrlsAsLinks;
|
||||
private TerminologyServiceOptions terminologyServiceOptions = new TerminologyServiceOptions();
|
||||
private ValidationOptions terminologyServiceOptions = new ValidationOptions();
|
||||
private boolean noSlowLookup;
|
||||
private List<String> codeSystemPropList = new ArrayList<>();
|
||||
|
||||
|
@ -2773,9 +2774,11 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
hierarchy = hierarchy || c.hasConcept();
|
||||
}
|
||||
CodeSystemNavigator csNav = new CodeSystemNavigator(cs);
|
||||
hierarchy = hierarchy || csNav.isRestructure();
|
||||
|
||||
addMapHeaders(addTableHeaderRowStandard(t, hierarchy, display, true, commentS, version, deprecated, lang, properties), maps);
|
||||
for (ConceptDefinitionComponent c : csNav.getConcepts(null)) {
|
||||
hasExtensions = addDefineRowToTable(t, c, 0, hierarchy || csNav.isRestructure(), display, commentS, version, deprecated, maps, cs.getUrl(), cs, lang, properties, csNav) || hasExtensions;
|
||||
hasExtensions = addDefineRowToTable(t, c, 0, hierarchy, display, commentS, version, deprecated, maps, cs.getUrl(), cs, lang, properties, csNav) || hasExtensions;
|
||||
}
|
||||
// if (langs.size() > 0) {
|
||||
// Collections.sort(langs);
|
||||
|
@ -3463,14 +3466,14 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
return "??Lang";
|
||||
}
|
||||
|
||||
private boolean addDefineRowToTable(XhtmlNode t, ConceptDefinitionComponent c, int i, boolean hasHierarchy, boolean hasDisplay, boolean comment, boolean version, boolean deprecated, List<UsedConceptMap> maps, String system, CodeSystem cs, String lang, List<PropertyComponent> properties, CodeSystemNavigator csNav) throws FHIRFormatError, DefinitionException, IOException {
|
||||
private boolean addDefineRowToTable(XhtmlNode t, ConceptDefinitionComponent c, int level, boolean hasHierarchy, boolean hasDisplay, boolean comment, boolean version, boolean deprecated, List<UsedConceptMap> maps, String system, CodeSystem cs, String lang, List<PropertyComponent> properties, CodeSystemNavigator csNav) throws FHIRFormatError, DefinitionException, IOException {
|
||||
boolean hasExtensions = false;
|
||||
XhtmlNode tr = t.tr();
|
||||
XhtmlNode td = tr.td();
|
||||
if (hasHierarchy) {
|
||||
td.addText(Integer.toString(i+1));
|
||||
td.addText(Integer.toString(level+1));
|
||||
td = tr.td();
|
||||
String s = Utilities.padLeft("", '\u00A0', i*2);
|
||||
String s = Utilities.padLeft("", '\u00A0', level*2);
|
||||
td.addText(s);
|
||||
}
|
||||
td.attribute("style", "white-space:nowrap").addText(c.getCode());
|
||||
|
@ -3481,31 +3484,7 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
|
||||
if (hasDisplay) {
|
||||
td = tr.td();
|
||||
if (c.hasDisplayElement()) {
|
||||
if (lang == null) {
|
||||
td.addText(c.getDisplay());
|
||||
} else if (lang.equals("*")) {
|
||||
boolean sl = false;
|
||||
for (ConceptDefinitionDesignationComponent cd : c.getDesignation())
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "display") && cd.hasLanguage() && !c.getDisplay().equalsIgnoreCase(cd.getValue()))
|
||||
sl = true;
|
||||
td.addText((sl ? cs.getLanguage("en")+": " : "")+c.getDisplay());
|
||||
for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) {
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "display") && cd.hasLanguage() && !c.getDisplay().equalsIgnoreCase(cd.getValue())) {
|
||||
td.br();
|
||||
td.addText(cd.getLanguage()+": "+cd.getValue());
|
||||
}
|
||||
}
|
||||
} else if (lang.equals(cs.getLanguage()) || (lang.equals("en") && !cs.hasLanguage())) {
|
||||
td.addText(c.getDisplay());
|
||||
} else {
|
||||
for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) {
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "display") && cd.hasLanguage() && cd.getLanguage().equals(lang)) {
|
||||
td.addText(cd.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
renderDisplayName(c, cs, lang, td);
|
||||
}
|
||||
td = tr.td();
|
||||
if (c != null &&
|
||||
|
@ -3632,20 +3611,61 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
td.i().tx("("+mapping.comp.getComment()+")");
|
||||
}
|
||||
}
|
||||
for (ConceptDefinitionComponent cc : csNav.getOtherChildren(c)) {
|
||||
List<ConceptDefinitionComponent> ocl = csNav.getOtherChildren(c);
|
||||
for (ConceptDefinitionComponent cc : csNav.getConcepts(c)) {
|
||||
hasExtensions = addDefineRowToTable(t, cc, level+1, hasHierarchy, hasDisplay, comment, version, deprecated, maps, system, cs, lang, properties, csNav) || hasExtensions;
|
||||
}
|
||||
for (ConceptDefinitionComponent cc : ocl) {
|
||||
tr = t.tr();
|
||||
td = tr.td();
|
||||
String s = Utilities.padLeft("", '.', i*2);
|
||||
td.addText(Integer.toString(level+2));
|
||||
td = tr.td();
|
||||
String s = Utilities.padLeft("", '\u00A0', (level+1)*2);
|
||||
td.addText(s);
|
||||
a = td.ah("#"+Utilities.nmtokenize(cc.getCode()));
|
||||
a.addText(c.getCode());
|
||||
}
|
||||
for (ConceptDefinitionComponent cc : csNav.getConcepts(c)) {
|
||||
hasExtensions = addDefineRowToTable(t, cc, i+1, hasHierarchy, hasDisplay, comment, version, deprecated, maps, system, cs, lang, properties, csNav) || hasExtensions;
|
||||
td.attribute("style", "white-space:nowrap");
|
||||
a = td.ah("#"+cs.getId()+"-" + Utilities.nmtokenize(cc.getCode()));
|
||||
a.addText(cc.getCode());
|
||||
if (hasDisplay) {
|
||||
td = tr.td();
|
||||
renderDisplayName(c, cs, lang, td);
|
||||
}
|
||||
int w = 1 + (deprecated ? 1 : 0) + (comment ? 1 : 0) + (version ? 1 : 0) + maps.size();
|
||||
if (properties != null) {
|
||||
w = w + properties.size();
|
||||
}
|
||||
td = tr.td().colspan(Integer.toString(w));
|
||||
}
|
||||
return hasExtensions;
|
||||
}
|
||||
|
||||
public void renderDisplayName(ConceptDefinitionComponent c, CodeSystem cs, String lang, XhtmlNode td) {
|
||||
if (c.hasDisplayElement()) {
|
||||
if (lang == null) {
|
||||
td.addText(c.getDisplay());
|
||||
} else if (lang.equals("*")) {
|
||||
boolean sl = false;
|
||||
for (ConceptDefinitionDesignationComponent cd : c.getDesignation())
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "display") && cd.hasLanguage() && !c.getDisplay().equalsIgnoreCase(cd.getValue()))
|
||||
sl = true;
|
||||
td.addText((sl ? cs.getLanguage("en")+": " : "")+c.getDisplay());
|
||||
for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) {
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "display") && cd.hasLanguage() && !c.getDisplay().equalsIgnoreCase(cd.getValue())) {
|
||||
td.br();
|
||||
td.addText(cd.getLanguage()+": "+cd.getValue());
|
||||
}
|
||||
}
|
||||
} else if (lang.equals(cs.getLanguage()) || (lang.equals("en") && !cs.hasLanguage())) {
|
||||
td.addText(c.getDisplay());
|
||||
} else {
|
||||
for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) {
|
||||
if (cd.getUse().is("http://terminology.hl7.org/CodeSystem/designation-usage", "display") && cd.hasLanguage() && cd.getLanguage().equals(lang)) {
|
||||
td.addText(cd.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean hasMarkdownInDefinitions(CodeSystem cs) {
|
||||
return ToolingExtensions.readBoolExtension(cs, "http://hl7.org/fhir/StructureDefinition/codesystem-use-markdown");
|
||||
|
@ -4922,11 +4942,11 @@ public class NarrativeGenerator implements INarrativeGenerator {
|
|||
return this;
|
||||
}
|
||||
|
||||
public TerminologyServiceOptions getTerminologyServiceOptions() {
|
||||
public ValidationOptions getTerminologyServiceOptions() {
|
||||
return terminologyServiceOptions;
|
||||
}
|
||||
|
||||
public void setTerminologyServiceOptions(TerminologyServiceOptions terminologyServiceOptions) {
|
||||
public void setTerminologyServiceOptions(ValidationOptions terminologyServiceOptions) {
|
||||
this.terminologyServiceOptions = terminologyServiceOptions;
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,7 @@ import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
|||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.TerminologyServiceOptions;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.xhtml.NodeType;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
@ -228,7 +229,7 @@ public class StructureMapUtilities {
|
|||
private ITransformerServices services;
|
||||
private ProfileKnowledgeProvider pkp;
|
||||
private Map<String, Integer> ids = new HashMap<String, Integer>();
|
||||
private TerminologyServiceOptions terminologyServiceOptions = new TerminologyServiceOptions();
|
||||
private ValidationOptions terminologyServiceOptions = new ValidationOptions();
|
||||
|
||||
public StructureMapUtilities(IWorkerContext worker, ITransformerServices services, ProfileKnowledgeProvider pkp) {
|
||||
super();
|
||||
|
@ -2969,11 +2970,11 @@ public class StructureMapUtilities {
|
|||
return null;
|
||||
}
|
||||
|
||||
public TerminologyServiceOptions getTerminologyServiceOptions() {
|
||||
public ValidationOptions getTerminologyServiceOptions() {
|
||||
return terminologyServiceOptions;
|
||||
}
|
||||
|
||||
public void setTerminologyServiceOptions(TerminologyServiceOptions terminologyServiceOptions) {
|
||||
public void setTerminologyServiceOptions(ValidationOptions terminologyServiceOptions) {
|
||||
this.terminologyServiceOptions = terminologyServiceOptions;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package org.hl7.fhir.utilities;
|
||||
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
|
||||
/*-
|
||||
* #%L
|
||||
* org.hl7.fhir.utilities
|
||||
|
@ -20,28 +22,19 @@ package org.hl7.fhir.utilities;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
public class TerminologyServiceOptions {
|
||||
private String language;
|
||||
/**
|
||||
* This class is superceded by TerminologyValidationOptions but retained here for backwards compatibility
|
||||
* @author graha
|
||||
*
|
||||
*/
|
||||
public class TerminologyServiceOptions extends ValidationOptions {
|
||||
|
||||
public TerminologyServiceOptions() {
|
||||
super();
|
||||
}
|
||||
|
||||
public TerminologyServiceOptions(String language) {
|
||||
super();
|
||||
this.language = language;
|
||||
|
||||
public TerminologyServiceOptions(String lang) {
|
||||
super(lang);
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
public void setLanguage(String language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
public String toJson() {
|
||||
return "\"lang\":\""+language+"\"";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
package org.hl7.fhir.utilities.validation;
|
||||
|
||||
public class ValidationOptions {
|
||||
private String language;
|
||||
private boolean useServer = true;
|
||||
private boolean useClient = true;
|
||||
private boolean guessSystem = false;
|
||||
|
||||
public ValidationOptions() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ValidationOptions(String language) {
|
||||
super();
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
|
||||
public boolean isUseServer() {
|
||||
return useServer;
|
||||
}
|
||||
|
||||
public boolean isUseClient() {
|
||||
return useClient;
|
||||
}
|
||||
|
||||
public boolean isGuessSystem() {
|
||||
return guessSystem;
|
||||
}
|
||||
|
||||
private ValidationOptions copy() {
|
||||
ValidationOptions n = new ValidationOptions(language);
|
||||
n.useServer = useServer;
|
||||
n.useClient = useClient;
|
||||
n.guessSystem = guessSystem;
|
||||
return n;
|
||||
}
|
||||
|
||||
public ValidationOptions setLanguage(String language) {
|
||||
ValidationOptions n = this.copy();
|
||||
n.language = language;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
public ValidationOptions noServer() {
|
||||
ValidationOptions n = this.copy();
|
||||
n.useServer = false;
|
||||
return n;
|
||||
}
|
||||
|
||||
public ValidationOptions noClient() {
|
||||
ValidationOptions n = this.copy();
|
||||
n.useClient = false;
|
||||
return n;
|
||||
}
|
||||
|
||||
public ValidationOptions guessSystem() {
|
||||
ValidationOptions n = this.copy();
|
||||
n.guessSystem = false;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
public String toJson() {
|
||||
return "\"lang\":\""+language+"\", \"useServer\":\""+Boolean.toString(useServer)+"\", \"useClient\":\""+Boolean.toString(useClient)+"\", \"guessSystem\":\""+Boolean.toString(guessSystem)+"\"";
|
||||
}
|
||||
}
|
|
@ -136,6 +136,7 @@ import org.hl7.fhir.utilities.TerminologyServiceOptions;
|
|||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.Utilities.DecimalStatus;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
||||
|
@ -914,7 +915,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
txTime = txTime + (System.nanoTime() - t);
|
||||
if (ss) {
|
||||
t = System.nanoTime();
|
||||
ValidationResult s = context.validateCode(new TerminologyServiceOptions(stack.workingLang), system, code, checkDisplay ? display : null);
|
||||
ValidationResult s = context.validateCode(new ValidationOptions(stack.workingLang), system, code, checkDisplay ? display : null);
|
||||
txTime = txTime + (System.nanoTime() - t);
|
||||
if (s == null)
|
||||
return true;
|
||||
|
@ -1071,7 +1072,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (!atLeastOneSystemIsSupported && binding.getStrength() == BindingStrength.EXAMPLE) {
|
||||
// ignore this since we can't validate but it doesn't matter..
|
||||
} else {
|
||||
ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), cc, valueset);
|
||||
ValidationResult vr = context.validateCode(new ValidationOptions(stack.workingLang), cc, valueset); // we're going to validate the codings directly
|
||||
if (!vr.isOk()) {
|
||||
bindingsOk = false;
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) {
|
||||
|
@ -1090,13 +1091,14 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
|
||||
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, stack);
|
||||
else if (!noExtensibleWarnings)
|
||||
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)+")");
|
||||
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
|
||||
txHint(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 is recommended to come from this value set) (codes = "+ccSummary(cc)+")");
|
||||
}
|
||||
}
|
||||
} else if (vr.getMessage()!=null) {
|
||||
res = false;
|
||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, vr.getMessage());
|
||||
} else {
|
||||
res = false;
|
||||
|
@ -1109,7 +1111,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
String nextCode = nextCoding.getCode();
|
||||
String nextSystem = nextCoding.getSystem();
|
||||
if (isNotBlank(nextCode) && isNotBlank(nextSystem) && context.supportsSystem(nextSystem)) {
|
||||
ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), nextSystem, nextCode, null);
|
||||
ValidationResult vr = context.validateCode(new ValidationOptions(stack.workingLang), nextSystem, nextCode, null);
|
||||
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);
|
||||
}
|
||||
|
@ -1139,7 +1141,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, "ValueSet " + describeReference(maxVSUrl) + " not found by validator")) {
|
||||
try {
|
||||
long t = System.nanoTime();
|
||||
ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), cc, valueset);
|
||||
ValidationResult vr = context.validateCode(new ValidationOptions(stack.workingLang), cc, valueset);
|
||||
txTime = txTime + (System.nanoTime() - t);
|
||||
if (!vr.isOk()) {
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||
|
@ -1159,7 +1161,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, "ValueSet " + describeReference(maxVSUrl) + " not found by validator")) {
|
||||
try {
|
||||
long t = System.nanoTime();
|
||||
ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), c, valueset);
|
||||
ValidationResult vr = context.validateCode(new ValidationOptions(stack.workingLang), c, valueset);
|
||||
txTime = txTime + (System.nanoTime() - t);
|
||||
if (!vr.isOk()) {
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||
|
@ -1179,7 +1181,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, "ValueSet " + describeReference(maxVSUrl) + " not found by validator")) {
|
||||
try {
|
||||
long t = System.nanoTime();
|
||||
ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), value, valueset);
|
||||
ValidationResult vr = context.validateCode(new ValidationOptions(stack.workingLang), value, valueset);
|
||||
txTime = txTime + (System.nanoTime() - t);
|
||||
if (!vr.isOk()) {
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||
|
@ -1229,7 +1231,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
long t = System.nanoTime();
|
||||
ValidationResult vr = null;
|
||||
if (binding.getStrength() != BindingStrength.EXAMPLE) {
|
||||
vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), c, valueset);
|
||||
vr = context.validateCode(new ValidationOptions(stack.workingLang), c, valueset);
|
||||
}
|
||||
txTime = txTime + (System.nanoTime() - t);
|
||||
if (vr != null && !vr.isOk()) {
|
||||
|
@ -1862,7 +1864,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
long t = System.nanoTime();
|
||||
ValidationResult vr = null;
|
||||
if (binding.getStrength() != BindingStrength.EXAMPLE) {
|
||||
vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), value, vs);
|
||||
vr = context.validateCode(new ValidationOptions(stack.workingLang), value, vs);
|
||||
}
|
||||
txTime = txTime + (System.nanoTime() - t);
|
||||
if (vr != null && !vr.isOk()) {
|
||||
|
@ -3502,7 +3504,7 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L
|
|||
}
|
||||
|
||||
long t = System.nanoTime();
|
||||
ValidationResult res = context.validateCode(new TerminologyServiceOptions(stack.workingLang), c, vs);
|
||||
ValidationResult res = context.validateCode(new ValidationOptions(stack.workingLang), c, vs);
|
||||
txTime = txTime + (System.nanoTime() - t);
|
||||
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");
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -17,7 +17,7 @@
|
|||
|
||||
<properties>
|
||||
<hapi_fhir_version>4.1.0</hapi_fhir_version>
|
||||
<validator_test_case_version>1.0.15-SNAPSHOT</validator_test_case_version>
|
||||
<validator_test_case_version>1.0.16-SNAPSHOT</validator_test_case_version>
|
||||
</properties>
|
||||
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
|
|
Loading…
Reference in New Issue