Error when ValueSet.compose.include.system refers to a ValueSet
This commit is contained in:
parent
f2e48e5dec
commit
df72ca604e
|
@ -1,11 +1,14 @@
|
|||
package org.hl7.fhir.r5.terminologies;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
import org.hl7.fhir.r5.model.Identifier;
|
||||
import org.hl7.fhir.utilities.json.model.JsonObject;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class TerminologyUtilities {
|
||||
|
||||
|
@ -24,4 +27,27 @@ public class TerminologyUtilities {
|
|||
}
|
||||
return oids;
|
||||
}
|
||||
|
||||
public static List<String> listSystems(ValueSet vs) {
|
||||
Set<String> res = new HashSet<>();
|
||||
for (ConceptSetComponent inc : vs.getCompose().getInclude()) {
|
||||
if (inc.hasSystem()) {
|
||||
if (inc.hasVersion()) {
|
||||
res.add(inc.getSystem()+"|"+inc.getVersion());
|
||||
} else {
|
||||
res.add(inc.getSystem());
|
||||
}
|
||||
}
|
||||
}
|
||||
for (ConceptSetComponent inc : vs.getCompose().getExclude()) {
|
||||
if (inc.hasSystem()) {
|
||||
if (inc.hasVersion()) {
|
||||
res.add(inc.getSystem()+"|"+inc.getVersion());
|
||||
} else {
|
||||
res.add(inc.getSystem());
|
||||
}
|
||||
}
|
||||
}
|
||||
return Utilities.sorted(res);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -281,8 +281,9 @@ public class ToolingExtensions {
|
|||
public static final String EXT_SUPPRESS_RESOURCE_TYPE = "http://hl7.org/fhir/tools/StructureDefinition/json-suppress-resourcetype";
|
||||
public static final String EXT_PROFILE_VIEW_HINT = "http://hl7.org/fhir/tools/StructureDefinition/view-hint";
|
||||
public static final String EXT_SNAPSHOT_BEHAVIOR = "http://hl7.org/fhir/tools/StructureDefinition/snapshot-behavior";
|
||||
public static final String EXT_EARLIEST_FHIR_VERSION = "http://hl7.org/fhir/StructureDefinition/earliestAllowedFHIRVersion";
|
||||
public static final String EXT_LATEST_FHIR_VERSION = "http://hl7.org/fhir/StructureDefinition/latestAllowedFHIRVersion";
|
||||
public static final String EXT_FHIRVERSION_SPECIFIC_USE = "http://hl7.org/fhir/StructureDefinition/version-specific-use";
|
||||
public static final String EXT_FHIRVERSION_SPECIFIC_USE_START = "startFhirVersion";
|
||||
public static final String EXT_FHIRVERSION_SPECIFIC_USE_END = "endFhirVersion";
|
||||
|
||||
// specific extension helpers
|
||||
|
||||
|
|
|
@ -227,8 +227,12 @@ public class I18nConstants {
|
|||
public static final String EXTENSION_CONTEXT_UNABLE_TO_FIND_PROFILE = "EXTENSION_CONTEXT_UNABLE_TO_FIND_PROFILE";
|
||||
public static final String EXTENSION_EXTM_CONTEXT_WRONG = "Extension_EXTM_Context_Wrong";
|
||||
public static final String EXTENSION_EXTM_CONTEXT_WRONG_XVER = "EXTENSION_EXTM_CONTEXT_WRONG_XVER";
|
||||
public static final String EXTENSION_EXTM_CONTEXT_WRONG_VER = "Extension_EXTM_Context_Wrong_VER";
|
||||
public static final String EXTENSION_EXTM_CONTEXT_WRONG_XVER_VER = "EXTENSION_EXTM_CONTEXT_WRONG_XVER_VER";
|
||||
public static final String EXTENSION_EXTP_CONTEXT_WRONG = "Extension_EXTP_Context_Wrong";
|
||||
public static final String EXTENSION_EXTP_CONTEXT_WRONG_XVER = "EXTENSION_EXTP_CONTEXT_WRONG_XVER";
|
||||
public static final String EXTENSION_EXTP_CONTEXT_WRONG_VER = "Extension_EXTP_Context_Wrong_VER";
|
||||
public static final String EXTENSION_EXTP_CONTEXT_WRONG_XVER_VER = "EXTENSION_EXTP_CONTEXT_WRONG_XVER_VER";
|
||||
public static final String EXTENSION_EXT_COUNT_MISMATCH = "Extension_EXT_Count_Mismatch";
|
||||
public static final String EXTENSION_EXT_COUNT_NOTFOUND = "Extension_EXT_Count_NotFound";
|
||||
public static final String EXTENSION_EXT_FIXED_BANNED = "Extension_EXT_Fixed_Banned";
|
||||
|
@ -1167,4 +1171,7 @@ public class I18nConstants {
|
|||
public static final String SD_DERIVATION_NO_CONCRETE = "SD_DERIVATION_NO_CONCRETE";
|
||||
public static final String EXTENSION_FHIR_VERSION_EARLIEST = "EXTENSION_FHIR_VERSION_EARLIEST";
|
||||
public static final String EXTENSION_FHIR_VERSION_LATEST = "EXTENSION_FHIR_VERSION_LATEST";
|
||||
public static final String VALUESET_INCLUDE_WRONG_VS = "VALUESET_INCLUDE_WRONG_VS";
|
||||
public static final String VALUESET_INCLUDE_WRONG_VS_HINT = "VALUESET_INCLUDE_WRONG_VS_HINT";
|
||||
public static final String VALUESET_INCLUDE_WRONG_VS_MANY = "VALUESET_INCLUDE_WRONG_VS_MANY";
|
||||
}
|
||||
|
|
|
@ -200,7 +200,9 @@ ERROR_GENERATING_SNAPSHOT = Error generating Snapshot: {0} (this usually arises
|
|||
EXTENSION_CONTEXT_UNABLE_TO_CHECK_PROFILE = The extension {0} specifies a context of {1} but the validator cannot check whether the profile is valid or not at this time
|
||||
EXTENSION_CONTEXT_UNABLE_TO_FIND_PROFILE = The extension {0} specifies a context of {1} but the validator cannot find that profile
|
||||
EXTENSION_EXTM_CONTEXT_WRONG_XVER = The modifier extension {0} from FHIR version {3} is not allowed to be used at this point (allowed = {1}; this element is [{2}; this is a warning since contexts may be renamed between FHIR versions)
|
||||
EXTENSION_EXTM_CONTEXT_WRONG_XVER_VER = The modifier extension {0} from FHIR version {3} is not allowed to be used at this point (allowed for this version = {1}; this element is [{2}; this is a warning since contexts may be renamed between FHIR versions)
|
||||
EXTENSION_EXTP_CONTEXT_WRONG_XVER = The extension {0} from FHIR version {3} is not allowed to be used at this point (allowed = {1}; this element is [{2}; this is a warning since contexts may be renamed between FHIR versions)
|
||||
EXTENSION_EXTP_CONTEXT_WRONG_XVER_VER = The extension {0} from FHIR version {3} is not allowed to be used at this point (allowed for this version = {1}; this element is [{2}; this is a warning since contexts may be renamed between FHIR versions)
|
||||
EXT_VER_URL_IGNORE = Extension URLs don''t have versions. The validator has ignored the version and processed the extension anyway
|
||||
EXT_VER_URL_MISLEADING = The extension URL contains a ''|'' which makes it look like a versioned URL, but it''s not, and this is confusing for implementers
|
||||
EXT_VER_URL_NOT_ALLOWED = The extension URL must not contain a version
|
||||
|
@ -228,7 +230,9 @@ Error_parsing_XHTML_ = Error parsing XHTML: {0}
|
|||
Error_reading__from_package__ = Error reading {0} from package {1}#{2}: {3}
|
||||
Error_validating_code_running_without_terminology_services = Unable to validate code ''{0}'' in system ''{1}'' because the validator is running without terminology services
|
||||
Extension_EXTM_Context_Wrong = The modifier extension {0} is not allowed to be used at this point (allowed = {1}; this element is {2})
|
||||
Extension_EXTM_Context_Wrong_VER = The modifier extension {0} is not allowed to be used at this point (allowed for this version = {1}; this element is {2})
|
||||
Extension_EXTP_Context_Wrong = The extension {0} is not allowed to be used at this point (allowed = {1}; this element is {2})
|
||||
Extension_EXTP_Context_Wrong_VER = The extension {0} is not allowed to be used at this point (allowed for this version = {1}; this element is {2})
|
||||
Extension_EXT_Count_Mismatch = Extensions count mismatch: expected {0} but found {1}
|
||||
Extension_EXT_Count_NotFound = Extension count mismatch: unable to find extension: {0}
|
||||
Extension_EXT_Fixed_Banned = No extensions allowed, as the specified fixed value doesn''t contain any extensions
|
||||
|
@ -1199,4 +1203,7 @@ VS_EXP_FILTER_UNK = ValueSet ''{0}'' Filter by property ''{1}'' and op ''{2}'' i
|
|||
CONCEPTMAP_VS_NOT_A_VS = Reference must be to a ValueSet, but found a {0} instead
|
||||
SD_DERIVATION_NO_CONCRETE = {0} is labeled as an abstract type, but no concrete descendants were found (check definitions - this is usually an error unless concrete definitions are in some other package)
|
||||
EXTENSION_FHIR_VERSION_EARLIEST = The definition of the extension ''{0}'' specifies that the earliest version it can be used with is {1} (v{2}), but this context of use is version {3} (v{4})
|
||||
EXTENSION_FHIR_VERSION_LATEST = The definition of the extension ''{0}'' specifies that the latest version it can be used with is {1} (v{2}), but this context of use is version {3} (v{4})
|
||||
EXTENSION_FHIR_VERSION_LATEST = The definition of the extension ''{0}'' specifies that the latest version it can be used with is {1} (v{2}), but this context of use is version {3} (v{4})
|
||||
VALUESET_INCLUDE_WRONG_VS = The system ''{0}'' is actually a value set
|
||||
VALUESET_INCLUDE_WRONG_VS_HINT = The system ''{0}'' is actually a value set, which itself refers to the system ''{1}'' so that may be what is intended here
|
||||
VALUESET_INCLUDE_WRONG_VS_MANY = The system ''{0}'' is actually a value set, which itself refers to the systems {1}
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.hl7.fhir.r5.model.Enumerations.FilterOperator;
|
|||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
||||
import org.hl7.fhir.r5.terminologies.TerminologyUtilities;
|
||||
import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome;
|
||||
import org.hl7.fhir.r5.terminologies.utilities.CodingValidationRequest;
|
||||
import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass;
|
||||
|
@ -303,6 +304,7 @@ public class ValueSetValidator extends BaseValidator {
|
|||
// can we get it from a terminology server?
|
||||
cs = context.findTxResource(CodeSystem.class, system, version);
|
||||
}
|
||||
boolean validateConcepts = true;
|
||||
if (cs != null) { // if it's null, we can't analyse this
|
||||
if (cs.getContent() == null) {
|
||||
warning(errors, "2024-03-06", IssueType.INVALID, stack, false, version == null ? I18nConstants.VALUESET_INCLUDE_CS_CONTENT : I18nConstants.VALUESET_INCLUDE_CSVER_CONTENT, system, "null", version);
|
||||
|
@ -315,15 +317,29 @@ public class ValueSetValidator extends BaseValidator {
|
|||
hint(errors, "2024-03-06", IssueType.INVALID, stack, false, version == null ? I18nConstants.VALUESET_INCLUDE_CS_CONTENT : I18nConstants.VALUESET_INCLUDE_CSVER_CONTENT, system, cs.getContent().toCode(), version);
|
||||
break;
|
||||
case SUPPLEMENT:
|
||||
validateConcepts = false;
|
||||
ok = rule(errors, "2024-03-06", IssueType.INVALID, stack, false, version == null ? I18nConstants.VALUESET_INCLUDE_CS_SUPPLEMENT : I18nConstants.VALUESET_INCLUDE_CSVER_SUPPLEMENT, system, cs.getSupplements(), version) && ok;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ValueSet vs = context.findTxResource(ValueSet.class, system, version);
|
||||
if (vs != null) {
|
||||
validateConcepts = false;
|
||||
List<String> systems = TerminologyUtilities.listSystems(vs);
|
||||
if (systems.size() == 0) {
|
||||
ok = rule(errors, "2025-01-09", IssueType.INVALID, stack, false, I18nConstants.VALUESET_INCLUDE_WRONG_VS, system) && ok;
|
||||
} else if (systems.size() == 1) {
|
||||
ok = rule(errors, "2025-01-09", IssueType.INVALID, stack, false, I18nConstants.VALUESET_INCLUDE_WRONG_VS_HINT, system, systems.get(0)) && ok;
|
||||
} else {
|
||||
ok = rule(errors, "2025-01-09", IssueType.INVALID, stack, false, I18nConstants.VALUESET_INCLUDE_WRONG_VS_MANY, system, CommaSeparatedStringBuilder.join(", ", systems)) && ok;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!noTerminologyChecks) {
|
||||
if (!noTerminologyChecks && validateConcepts) {
|
||||
boolean systemOk = true;
|
||||
int cc = 0;
|
||||
List<VSCodingValidationRequest> batch = new ArrayList<>();
|
||||
|
@ -336,7 +352,7 @@ public class ValueSetValidator extends BaseValidator {
|
|||
for (Element concept : concepts) {
|
||||
// we treat the first differently because we want to know if the system is worth validating. if it is, then we batch the rest
|
||||
if (first) {
|
||||
systemOk = validateValueSetIncludeConcept(errors, concept, stack, stack.push(concept, cc, null, null), system, version, csChecker);
|
||||
systemOk = validateValueSetIncludeConcept(errors, concept, stack, stack.push(concept, cc, null, null), system, version, csChecker, cs != null);
|
||||
first = false;
|
||||
} else if (systemOk) {
|
||||
batch.add(prepareValidateValueSetIncludeConcept(errors, concept, stack.push(concept, cc, null, null), system, version, csChecker));
|
||||
|
@ -390,7 +406,7 @@ public class ValueSetValidator extends BaseValidator {
|
|||
}
|
||||
|
||||
|
||||
private boolean validateValueSetIncludeConcept(List<ValidationMessage> errors, Element concept, NodeStack stackInc, NodeStack stack, String system, String version, CodeSystemChecker slv) {
|
||||
private boolean validateValueSetIncludeConcept(List<ValidationMessage> errors, Element concept, NodeStack stackInc, NodeStack stack, String system, String version, CodeSystemChecker slv, boolean locallyKnownCodeSystem) {
|
||||
String code = concept.getChildValue("code");
|
||||
String display = concept.getChildValue("display");
|
||||
slv.checkConcept(code, display);
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
"#cs1|null" : null,
|
||||
"#cs|null" : null,
|
||||
"http://something|null" : null,
|
||||
"http://snomed.info/sct|null" : null
|
||||
"http://snomed.info/sct|null" : null,
|
||||
"http://hl7.org/fhir/ValueSet/FHIR-version|5.0.0" : null
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue