Handle unknown code systems better when checking codes from unknown systems

This commit is contained in:
Grahame Grieve 2020-08-13 12:36:36 +10:00
parent 008dc84546
commit fa89778809
5 changed files with 35 additions and 13 deletions

View File

@ -970,7 +970,6 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
for (ConceptSetComponent inc : vs.getCompose().getExclude()) {
addDependentResources(pin, inc);
}
}
private void addDependentResources(Parameters pin, ConceptSetComponent inc) {

View File

@ -36,6 +36,6 @@ import org.hl7.fhir.r5.utils.EOperationOutcome;
public interface ValueSetChecker {
boolean codeInValueSet(String system, String code) throws ETooCostly, EOperationOutcome, Exception;
Boolean codeInValueSet(String system, String code) throws ETooCostly, EOperationOutcome, Exception;
}

View File

@ -54,6 +54,7 @@ import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceDesignationComponent;
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.i18n.I18nConstants;
@ -98,11 +99,18 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
}
}
if (valueset != null && options.getValueSetMode() != ValueSetMode.NO_MEMBERSHIP_CHECK) {
boolean ok = false;
Boolean result = false;
for (Coding c : code.getCoding()) {
ok = ok || codeInValueSet(c.getSystem(), c.getCode());
Boolean ok = codeInValueSet(c.getSystem(), c.getCode());
if (ok == null && result == false) {
result = null;
} else if (ok) {
result = true;
}
}
if (!ok) {
if (result == null) {
warnings.add(0, context.formatMessage(I18nConstants.UNABLE_TO_CHECK_IF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_, valueset.getUrl()));
} else if (!result) {
errors.add(0, context.formatMessage(I18nConstants.NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_, valueset.getUrl()));
}
}
@ -119,7 +127,7 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
String warningMessage = null;
// first, we validate the concept itself
ValidationResult res =null;
ValidationResult res = null;
boolean inExpansion = false;
String system = code.hasSystem() ? code.getSystem() : getValueSetSystem();
if (options.getValueSetMode() != ValueSetMode.CHECK_MEMERSHIP_ONLY) {
@ -416,24 +424,34 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
}
@Override
public boolean codeInValueSet(String system, String code) throws FHIRException {
public Boolean codeInValueSet(String system, String code) throws FHIRException {
Boolean result = false;
if (valueset.hasExpansion()) {
return checkExpansion(new Coding(system, code, null));
} else if (valueset.hasCompose()) {
boolean ok = false;
for (ConceptSetComponent vsi : valueset.getCompose().getInclude()) {
ok = ok || inComponent(vsi, system, code, valueset.getCompose().getInclude().size() == 1);
Boolean ok = inComponent(vsi, system, code, valueset.getCompose().getInclude().size() == 1);
if (ok == null && result == false) {
result = null;
} else if (ok) {
result = true;
break;
}
}
for (ConceptSetComponent vsi : valueset.getCompose().getExclude()) {
ok = ok && !inComponent(vsi, system, code, valueset.getCompose().getInclude().size() == 1);
Boolean nok = inComponent(vsi, system, code, valueset.getCompose().getInclude().size() == 1);
if (nok == null && result == false) {
result = null;
} else if (!nok) {
result = false;
}
}
return ok;
}
return false;
return result;
}
private boolean inComponent(ConceptSetComponent vsi, String system, String code, boolean only) throws FHIRException {
private Boolean inComponent(ConceptSetComponent vsi, String system, String code, boolean only) throws FHIRException {
for (UriType uri : vsi.getValueSet()) {
if (inImport(uri.getValue(), system, code)) {
return true;
@ -463,6 +481,9 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
vs.setUrl(Utilities.makeUuidUrn());
vs.getCompose().addInclude(vsi);
ValidationResult res = context.validateCode(options.noClient(), new Coding(system, code, null), vs);
if (res.getErrorClass() == TerminologyServiceErrorClass.UNKNOWN || res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED || res.getErrorClass() == TerminologyServiceErrorClass.VALUESET_UNSUPPORTED) {
return null;
}
return res.isOk();
} else {
if (vsi.hasFilter()) {

View File

@ -230,6 +230,7 @@ public class I18nConstants {
public static final String NEEDS_A_SNAPSHOT = "needs_a_snapshot";
public static final String NODE_TYPE__IS_NOT_ALLOWED = "Node_type__is_not_allowed";
public static final String NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_ = "None_of_the_provided_codes_are_in_the_value_set_";
public static final String UNABLE_TO_CHECK_IF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_ = "UNABLE_TO_CHECK_IF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_";
public static final String NOT_DONE_YET = "Not_done_yet";
public static final String NOT_DONE_YET_CANT_FETCH_ = "not_done_yet_cant_fetch_";
public static final String NOT_DONE_YET_VALIDATORHOSTSERVICESCHECKFUNCTION = "Not_done_yet_ValidatorHostServicescheckFunction";

View File

@ -596,3 +596,4 @@ BUNDLE_RULE_NONE = No Rule
BUNDLE_RULE_UNKNOWN = Bundle Rule refers to invalid resource {0}
BUNDLE_RULE_INVALID_INDEX = Bundle Rules index is invalid ({0})
BUNDLE_RULE_PROFILE_UNKNOWN = Bundle Rules profile {1} is unknown for {0}
UNABLE_TO_CHECK_IF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_ = Unable to determine whether the provided codes are in the value set {0} because the value set or code system is not known to the validator