fix problem validating LOINC codes

This commit is contained in:
Grahame Grieve 2019-09-02 13:48:19 +10:00
parent 09b74eab50
commit ea913ceb30
2 changed files with 39 additions and 8 deletions

View File

@ -30,6 +30,7 @@ import org.hl7.fhir.r5.model.Meta;
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.ConceptSetComponent; import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r5.model.ValueSet.FilterOperator;
import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.utilities.StandardsStatus; import org.hl7.fhir.utilities.StandardsStatus;
import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.Utilities;
@ -142,9 +143,39 @@ public class ValueSetUtilities {
public static ValueSet generateImplicitValueSet(String uri) { public static ValueSet generateImplicitValueSet(String uri) {
if (uri.startsWith("http://snomed.info/sct")) if (uri.startsWith("http://snomed.info/sct"))
return generateImplicitSnomedValueSet(uri); return generateImplicitSnomedValueSet(uri);
if (uri.startsWith("http://loinc.org/vs"))
return generateImplicitLoincValueSet(uri);
return null; return null;
} }
private static ValueSet generateImplicitLoincValueSet(String uri) {
if ("http://loinc.org/vs".equals(uri))
return makeLoincValueSet();
if (uri.startsWith("http://loinc.org/vs/LL"))
return makeAnswerList(makeLoincValueSet(), uri);
return null;
}
private static ValueSet makeAnswerList(ValueSet vs, String uri) {
vs.setUrl(uri);
String c = uri.substring(20);
vs.setName("LOINCAnswers"+c);
vs.setTitle("LOINC Answer Codes for "+c);
vs.getCompose().getIncludeFirstRep().addFilter().setProperty("LIST").setOp(FilterOperator.EQUAL).setValue(c);
return vs;
}
private static ValueSet makeLoincValueSet() {
ValueSet vs = new ValueSet();
vs.setUrl("http://loinc.org/vs");
vs.setName("LOINCCodes");
vs.setTitle("All LOINC codes");
vs.setCopyright("This content LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the LOINC Committee, and available at no cost under the license at http://loinc.org/terms-of-use");
vs.setStatus(PublicationStatus.ACTIVE);
vs.getCompose().addInclude().setSystem("http://loinc.org");
return vs;
}
private static ValueSet generateImplicitSnomedValueSet(String uri) { private static ValueSet generateImplicitSnomedValueSet(String uri) {
if ("http://snomed.info/sct?fhir_vs".equals(uri)) if ("http://snomed.info/sct?fhir_vs".equals(uri))
return makeImplicitSnomedValueSet(uri); return makeImplicitSnomedValueSet(uri);

View File

@ -1021,7 +1021,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, binding != null, "Binding for " + path + " missing (cc)")) { if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, binding != null, "Binding for " + path + " missing (cc)")) {
if (binding.hasValueSet()) { if (binding.hasValueSet()) {
ValueSet valueset = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl()); ValueSet valueset = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl());
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, "ValueSet " + describeReference(binding.getValueSet()) + " not found")) { if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, "ValueSet " + describeReference(binding.getValueSet()) + " not found by validator")) {
try { try {
CodeableConcept cc = ObjectConverter.readAsCodeableConcept(element); CodeableConcept cc = ObjectConverter.readAsCodeableConcept(element);
if (!cc.hasCoding()) { if (!cc.hasCoding()) {
@ -1109,7 +1109,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
private void checkMaxValueSet(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, String maxVSUrl, CodeableConcept cc, NodeStack stack) { 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 by validator")) {
try { try {
long t = System.nanoTime(); long t = System.nanoTime();
ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), cc, valueset); ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), cc, valueset);
@ -1129,7 +1129,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
private void checkMaxValueSet(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, String maxVSUrl, Coding c, NodeStack stack) { 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 by validator")) {
try { try {
long t = System.nanoTime(); long t = System.nanoTime();
ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), c, valueset); ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), c, valueset);
@ -1149,7 +1149,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
private void checkMaxValueSet(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, String maxVSUrl, String value, NodeStack stack) { 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 by validator")) {
try { try {
long t = System.nanoTime(); long t = System.nanoTime();
ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), value, valueset); ValidationResult vr = context.validateCode(new TerminologyServiceOptions(stack.workingLang), value, valueset);
@ -1195,7 +1195,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
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")) {
if (binding.hasValueSet()) { if (binding.hasValueSet()) {
ValueSet valueset = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl()); ValueSet valueset = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl());
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, "ValueSet " + describeReference(binding.getValueSet()) + " not found")) { if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, "ValueSet " + describeReference(binding.getValueSet()) + " not found by validator")) {
try { try {
Coding c = ObjectConverter.readAsCoding(element); Coding c = ObjectConverter.readAsCoding(element);
long t = System.nanoTime(); long t = System.nanoTime();
@ -1815,7 +1815,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
ElementDefinitionBindingComponent binding = elementContext.getBinding(); ElementDefinitionBindingComponent binding = elementContext.getBinding();
if (binding.hasValueSet()) { if (binding.hasValueSet()) {
ValueSet vs = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl()); ValueSet vs = resolveBindingReference(profile, binding.getValueSet(), profile.getUrl());
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, vs != null, "ValueSet {0} not found", describeReference(binding.getValueSet()))) { if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, vs != null, "ValueSet {0} not found by validator", describeReference(binding.getValueSet()))) {
long t = System.nanoTime(); long t = System.nanoTime();
ValidationResult vr = null; ValidationResult vr = null;
if (binding.getStrength() != BindingStrength.EXAMPLE) { if (binding.getStrength() != BindingStrength.EXAMPLE) {
@ -3449,7 +3449,7 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L
private void validateAnswerCode(List<ValidationMessage> errors, Element value, NodeStack stack, Questionnaire qSrc, String ref, boolean theOpenChoice) { private void validateAnswerCode(List<ValidationMessage> errors, Element value, NodeStack stack, Questionnaire qSrc, String ref, boolean theOpenChoice) {
ValueSet vs = resolveBindingReference(qSrc, ref, qSrc.getUrl()); ValueSet vs = resolveBindingReference(qSrc, ref, qSrc.getUrl());
if (warning(errors, IssueType.CODEINVALID, value.line(), value.col(), stack.getLiteralPath(), vs != null, "ValueSet " + describeReference(ref) + " not found")) { if (warning(errors, IssueType.CODEINVALID, value.line(), value.col(), stack.getLiteralPath(), vs != null, "ValueSet " + describeReference(ref) + " not found by validator")) {
try { try {
Coding c = ObjectConverter.readAsCoding(value); Coding c = ObjectConverter.readAsCoding(value);
if (isBlank(c.getCode()) && isBlank(c.getSystem()) && isNotBlank(c.getDisplay())) { if (isBlank(c.getCode()) && isBlank(c.getSystem()) && isNotBlank(c.getDisplay())) {
@ -4535,7 +4535,7 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L
for (String profile : profiles.getCanonicalUrls()) { for (String profile : profiles.getCanonicalUrls()) {
StructureDefinition p = context.fetchResource(StructureDefinition.class, profile); StructureDefinition p = context.fetchResource(StructureDefinition.class, profile);
if (p == null) if (p == null)
throw new DefinitionException("StructureDefinition '" + profile + "' not found"); throw new DefinitionException("StructureDefinition '" + profile + "' not found by validator");
profiles.getDefinitions().add(p); profiles.getDefinitions().add(p);
} }
} }