support validation against code system fragments

This commit is contained in:
Grahame Grieve 2020-04-22 16:43:32 +10:00
parent bcde2d2f46
commit 4cbf328e54
3 changed files with 30 additions and 5 deletions

View File

@ -112,10 +112,17 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
if (system == null && !code.hasDisplay()) { // dealing with just a plain code (enum) if (system == null && !code.hasDisplay()) { // dealing with just a plain code (enum)
system = systemForCodeInValueSet(code.getCode()); system = systemForCodeInValueSet(code.getCode());
} }
if (!code.hasSystem()) if (!code.hasSystem()) {
if (options.isGuessSystem() && system == null && Utilities.isAbsoluteUrl(code.getCode())) {
system = "urn:ietf:rfc:3986"; // this arises when using URIs bound to value sets
}
code.setSystem(system); code.setSystem(system);
}
inExpansion = checkExpansion(code); inExpansion = checkExpansion(code);
CodeSystem cs = context.fetchCodeSystem(system); CodeSystem cs = context.fetchCodeSystem(system);
if (cs == null) {
cs = findSpecialCodeSystem(system);
}
if (cs == null) { if (cs == null) {
warningMessage = "Unable to resolve system "+system+" - system is not specified or implicit"; warningMessage = "Unable to resolve system "+system+" - system is not specified or implicit";
if (!inExpansion) if (!inExpansion)
@ -123,7 +130,7 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
} }
if (cs!=null && cs.getContent() != CodeSystemContentMode.COMPLETE) { if (cs!=null && cs.getContent() != CodeSystemContentMode.COMPLETE) {
warningMessage = "Unable to resolve system "+system+" - system is not complete"; warningMessage = "Unable to resolve system "+system+" - system is not complete";
if (!inExpansion) if (!inExpansion && cs.getContent() != CodeSystemContentMode.FRAGMENT) // we're going to give it a go if it's a fragment
throw new FHIRException(warningMessage); throw new FHIRException(warningMessage);
} }
@ -147,6 +154,17 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
return res; return res;
} }
private CodeSystem findSpecialCodeSystem(String system) {
if ("urn:ietf:rfc:3986".equals(system)) {
CodeSystem cs = new CodeSystem();
cs.setUrl(system);
cs.setUserData("tx.cs.special", new URICodeSystem());
cs.setContent(CodeSystemContentMode.COMPLETE);
return cs;
}
return null;
}
boolean checkExpansion(Coding code) { boolean checkExpansion(Coding code) {
if (valueset==null || !valueset.hasExpansion()) if (valueset==null || !valueset.hasExpansion())
return false; return false;
@ -164,9 +182,14 @@ public class ValueSetCheckerSimple implements ValueSetChecker {
} }
private ValidationResult validateCode(Coding code, CodeSystem cs) { private ValidationResult validateCode(Coding code, CodeSystem cs) {
ConceptDefinitionComponent cc = findCodeInConcept(cs.getConcept(), code.getCode()); ConceptDefinitionComponent cc = cs.hasUserData("tx.cs.special") ? ((SpecialCodeSystem) cs.getUserData("tx.cs.special")).findConcept(code) : findCodeInConcept(cs.getConcept(), code.getCode());
if (cc == null) if (cc == null) {
return new ValidationResult(IssueSeverity.ERROR, context.formatMessage(I18nConstants.UNKNOWN_CODE__IN_, gen(code), cs.getUrl())); if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
return new ValidationResult(IssueSeverity.ERROR, context.formatMessage(I18nConstants.UNKNOWN_CODE__IN_FRAGMENT, gen(code), cs.getUrl()));
} else {
return new ValidationResult(IssueSeverity.ERROR, context.formatMessage(I18nConstants.UNKNOWN_CODE__IN_, gen(code), cs.getUrl()));
}
}
if (code.getDisplay() == null) if (code.getDisplay() == null)
return new ValidationResult(cc); return new ValidationResult(cc);
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();

View File

@ -419,6 +419,7 @@ public class I18nConstants {
public final static String UNABLE_TO_CONNECT_TO_TERMINOLOGY_SERVER_USE_PARAMETER_TX_NA_TUN_RUN_WITHOUT_USING_TERMINOLOGY_SERVICES_TO_VALIDATE_LOINC_SNOMED_ICDX_ETC_ERROR__ = "Unable_to_connect_to_terminology_server_Use_parameter_tx_na_tun_run_without_using_terminology_services_to_validate_LOINC_SNOMED_ICDX_etc_Error__"; public final static String UNABLE_TO_CONNECT_TO_TERMINOLOGY_SERVER_USE_PARAMETER_TX_NA_TUN_RUN_WITHOUT_USING_TERMINOLOGY_SERVICES_TO_VALIDATE_LOINC_SNOMED_ICDX_ETC_ERROR__ = "Unable_to_connect_to_terminology_server_Use_parameter_tx_na_tun_run_without_using_terminology_services_to_validate_LOINC_SNOMED_ICDX_etc_Error__";
public final static String DISPLAY_NAME_FOR__SHOULD_BE_ONE_OF__INSTEAD_OF_ = "Display_Name_for__should_be_one_of__instead_of_"; public final static String DISPLAY_NAME_FOR__SHOULD_BE_ONE_OF__INSTEAD_OF_ = "Display_Name_for__should_be_one_of__instead_of_";
public final static String UNKNOWN_CODE__IN_ = "Unknown_Code__in_"; public final static String UNKNOWN_CODE__IN_ = "Unknown_Code__in_";
public final static String UNKNOWN_CODE__IN_FRAGMENT = "UNKNOWN_CODE__IN_FRAGMENT";
public final static String CODE_FOUND_IN_EXPANSION_HOWEVER_ = "Code_found_in_expansion_however_"; public final static String CODE_FOUND_IN_EXPANSION_HOWEVER_ = "Code_found_in_expansion_however_";
public final static String NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_ = "None_of_the_provided_codes_are_in_the_value_set_"; public final static String NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_ = "None_of_the_provided_codes_are_in_the_value_set_";
public final static String CODING_HAS_NO_SYSTEM__CANNOT_VALIDATE = "Coding_has_no_system__cannot_validate"; public final static String CODING_HAS_NO_SYSTEM__CANNOT_VALIDATE = "Coding_has_no_system__cannot_validate";

View File

@ -419,6 +419,7 @@ Error_parsing_ = Error parsing {0}:{1}
Unable_to_connect_to_terminology_server_Use_parameter_tx_na_tun_run_without_using_terminology_services_to_validate_LOINC_SNOMED_ICDX_etc_Error__ = Unable to connect to terminology server. Use parameter ''-tx n/a'' tun run without using terminology services to validate LOINC, SNOMED, ICD-X etc. Error = {0} Unable_to_connect_to_terminology_server_Use_parameter_tx_na_tun_run_without_using_terminology_services_to_validate_LOINC_SNOMED_ICDX_etc_Error__ = Unable to connect to terminology server. Use parameter ''-tx n/a'' tun run without using terminology services to validate LOINC, SNOMED, ICD-X etc. Error = {0}
Display_Name_for__should_be_one_of__instead_of_ = Display Name for {0}#{1} should be one of ''{2}'' instead of ''{3}'' Display_Name_for__should_be_one_of__instead_of_ = Display Name for {0}#{1} should be one of ''{2}'' instead of ''{3}''
Unknown_Code__in_ = Unknown Code {0} in {1} Unknown_Code__in_ = Unknown Code {0} in {1}
UNKNOWN_CODE__IN_FRAGMENT = Unknown Code {0} in {1} - note that the code system is labelled as a fragment, so the code may be valid in some other fragment
Code_found_in_expansion_however_ = Code found in expansion, however: {0} Code_found_in_expansion_however_ = Code found in expansion, however: {0}
None_of_the_provided_codes_are_in_the_value_set_ = None of the provided codes are in the value set {0} None_of_the_provided_codes_are_in_the_value_set_ = None of the provided codes are in the value set {0}
Coding_has_no_system__cannot_validate = Coding has no system - cannot validate Coding_has_no_system__cannot_validate = Coding has no system - cannot validate