make HL7 WG validation rule publication dependent
This commit is contained in:
parent
a0b87c7947
commit
d7d2ea50f3
|
@ -176,6 +176,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
|
|||
protected XVerExtensionManager xverManager;
|
||||
protected IValidatorResourceFetcher fetcher;
|
||||
protected IValidationPolicyAdvisor policyAdvisor;
|
||||
protected boolean noTerminologyChecks;
|
||||
|
||||
// these two related to removing warnings on extensible bindings in structures that have derivatives that replace their bindings
|
||||
protected List<TrackedLocationRelatedMessage> trackedMessages = new ArrayList<>();
|
||||
|
@ -235,6 +236,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
|
|||
this.baseOptions = parent.baseOptions;
|
||||
this.fetcher = parent.fetcher;
|
||||
this.policyAdvisor = parent.policyAdvisor;
|
||||
this.noTerminologyChecks = parent.noTerminologyChecks;
|
||||
}
|
||||
|
||||
private boolean doingLevel(IssueSeverity error) {
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.hl7.fhir.r5.elementmodel.Element;
|
|||
import org.hl7.fhir.r5.utils.XVerExtensionManager;
|
||||
import org.hl7.fhir.r5.utils.validation.ValidatorSession;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
||||
|
@ -76,8 +77,20 @@ public abstract class CodeSystemChecker extends BaseValidator {
|
|||
|
||||
public PropertyValidationRules rulesForFilter(String property, EnumSet<PropertyOperation> ops) {
|
||||
switch (property) {
|
||||
case "concept" : return new PropertyValidationRules(PropertyFilterType.Code, CodeValidationRule.Error, addToOps(ops, PropertyOperation.Equals, PropertyOperation.In, PropertyOperation.IsA, PropertyOperation.DescendentOf, PropertyOperation.DescendentLeaf, PropertyOperation.IsNotA, PropertyOperation.NotIn));
|
||||
case "code" : return new PropertyValidationRules(PropertyFilterType.Code, CodeValidationRule.Error, addToOps(ops, PropertyOperation.Equals, PropertyOperation.RegEx));
|
||||
case "concept" :
|
||||
return new PropertyValidationRules(PropertyFilterType.Code, CodeValidationRule.Error,
|
||||
VersionUtilities.isR5Plus(context.getVersion()) ?
|
||||
addToOps(ops, PropertyOperation.Equals, PropertyOperation.In, PropertyOperation.IsA, PropertyOperation.DescendentOf,
|
||||
PropertyOperation.DescendentLeaf, PropertyOperation.IsNotA, PropertyOperation.Generalizes, PropertyOperation.ChildOf, PropertyOperation.NotIn) :
|
||||
addToOps(ops, PropertyOperation.Equals, PropertyOperation.In, PropertyOperation.IsA, PropertyOperation.DescendentOf,
|
||||
PropertyOperation.IsNotA, PropertyOperation.Generalizes, PropertyOperation.NotIn));
|
||||
case "code" :
|
||||
return new PropertyValidationRules(PropertyFilterType.Code, CodeValidationRule.Error,
|
||||
VersionUtilities.isR5Plus(context.getVersion()) ?
|
||||
addToOps(ops, PropertyOperation.RegEx, PropertyOperation.Equals, PropertyOperation.In, PropertyOperation.IsA, PropertyOperation.DescendentOf,
|
||||
PropertyOperation.DescendentLeaf, PropertyOperation.IsNotA, PropertyOperation.Generalizes, PropertyOperation.ChildOf, PropertyOperation.NotIn) :
|
||||
addToOps(ops, PropertyOperation.RegEx, PropertyOperation.Equals, PropertyOperation.In, PropertyOperation.IsA, PropertyOperation.DescendentOf,
|
||||
PropertyOperation.IsNotA, PropertyOperation.Generalizes, PropertyOperation.NotIn));
|
||||
case "status" : return new PropertyValidationRules(PropertyFilterType.Code, CodeValidationRule.None, ops);
|
||||
case "inactive" : return new PropertyValidationRules(PropertyFilterType.Boolean,null, ops);
|
||||
case "effectiveDate" : return new PropertyValidationRules(PropertyFilterType.DateTime, null, ops);
|
||||
|
|
|
@ -565,7 +565,6 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
private boolean errorForUnknownProfiles;
|
||||
private boolean noInvariantChecks;
|
||||
private boolean wantInvariantInMessage;
|
||||
private boolean noTerminologyChecks;
|
||||
private boolean hintAboutNonMustSupport;
|
||||
private boolean showMessagesFromReferences;
|
||||
private String validationLanguage;
|
||||
|
@ -6010,7 +6009,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
}
|
||||
|
||||
if (rule(errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), wg != null || url.contains("http://hl7.org/fhir/sid"), I18nConstants.VALIDATION_HL7_WG_NEEDED, ToolingExtensions.EXT_WORKGROUP)) {
|
||||
if (rule(errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), wg != null || url.contains("http://hl7.org/fhir/sid") || !forPublication, I18nConstants.VALIDATION_HL7_WG_NEEDED, ToolingExtensions.EXT_WORKGROUP)) {
|
||||
if (wg != null) {
|
||||
HL7WorkGroup wgd = HL7WorkGroups.find(wg);
|
||||
if (rule(errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), wgd != null, I18nConstants.VALIDATION_HL7_WG_UNKNOWN, wg)) {
|
||||
|
|
|
@ -638,7 +638,7 @@ public class CodeSystemValidator extends BaseValidator {
|
|||
|
||||
private boolean validateSupplementConcept(List<ValidationMessage> errors, Element concept, NodeStack stack, String supp, ValidationOptions options) {
|
||||
String code = concept.getChildValue("code");
|
||||
if (!Utilities.noString(code)) {
|
||||
if (!Utilities.noString(code) && !noTerminologyChecks) {
|
||||
var canonical = new CanonicalPair(supp);
|
||||
org.hl7.fhir.r5.terminologies.utilities.ValidationResult res = context.validateCode(options, canonical.getUrl(), canonical.getVersion(), code, null);
|
||||
return rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), res.isOk(), I18nConstants.CODESYSTEM_CS_SUPP_INVALID_CODE, supp, code);
|
||||
|
|
|
@ -161,7 +161,7 @@ public class ConceptMapValidator extends BaseValidator {
|
|||
if (!batch.isEmpty()) {
|
||||
if (batch.size() > TOO_MANY_CODES_TO_VALIDATE) {
|
||||
ok = hint(errors, "2023-09-06", IssueType.BUSINESSRULE, stack.getLiteralPath(), false, I18nConstants.CONCEPTMAP_VS_TOO_MANY_CODES, batch.size()) && ok;
|
||||
} else {
|
||||
} else if (!noTerminologyChecks) {
|
||||
try {
|
||||
long t = System.currentTimeMillis();
|
||||
context.validateCodeBatch(ValidationOptions.defaults(), batch, null);
|
||||
|
@ -313,7 +313,7 @@ public class ConceptMapValidator extends BaseValidator {
|
|||
if (display != null) {
|
||||
warning(errors, "2023-03-05", IssueType.REQUIRED, code.line(), code.col(), cstack.getLiteralPath(), CodeSystemUtilities.checkDisplay(ctxt.source.cs, cd, display.getValue()), I18nConstants.CONCEPTMAP_GROUP_SOURCE_DISPLAY_INVALID, display.getValue(), CommaSeparatedStringBuilder.joinWrapped(", ", "'", "'", CodeSystemUtilities.getDisplays(ctxt.source.cs, cd)), ctxt.source.cs.getVersionedUrl()+"#"+cd.getCode());
|
||||
}
|
||||
if (ctxt.hasSourceVS() && ctxt.source != null) {
|
||||
if (!noTerminologyChecks && ctxt.hasSourceVS() && ctxt.source != null) {
|
||||
ValidationResult vr = context.validateCode(options.withCheckValueSetOnly().withNoServer(), ctxt.source.url, ctxt.source.version, c, null, ctxt.sourceScope.vs);
|
||||
if (!warningOrError(ctxt.source.cs.getContent() == CodeSystemContentMode.COMPLETE, errors, "2023-09-06", IssueType.REQUIRED, code.line(), code.col(), cstack.getLiteralPath(), vr.isOk(), I18nConstants.CONCEPTMAP_GROUP_SOURCE_CODE_INVALID_VS, c, ctxt.sourceScope.vs.getVersionedUrl())) {
|
||||
ok = (ctxt.source.cs.getContent() != CodeSystemContentMode.COMPLETE) & ok;
|
||||
|
@ -350,7 +350,7 @@ public class ConceptMapValidator extends BaseValidator {
|
|||
if (display != null) {
|
||||
warning(errors, "2023-03-05", IssueType.REQUIRED, code.line(), code.col(), cstack.getLiteralPath(), CodeSystemUtilities.checkDisplay(ctxt.target.cs, cd, display.getValue()), I18nConstants.CONCEPTMAP_GROUP_TARGET_DISPLAY_INVALID, display.getValue(), CommaSeparatedStringBuilder.joinWrapped(", ", "'", "'", CodeSystemUtilities.getDisplays(ctxt.target.cs, cd)), ctxt.target.cs.getVersionedUrl()+"#"+cd.getCode());
|
||||
}
|
||||
if (ctxt.hasTargetVS() && ctxt.target != null) {
|
||||
if (!!noTerminologyChecks && ctxt.hasTargetVS() && ctxt.target != null) {
|
||||
ValidationResult vr = context.validateCode(options.withCheckValueSetOnly().withNoServer(), ctxt.target.url, ctxt.target.version, c, null, ctxt.targetScope.vs);
|
||||
if (!warningOrError(ctxt.target.cs.getContent() == CodeSystemContentMode.COMPLETE, errors, "2023-09-06", IssueType.REQUIRED, code.line(), code.col(), cstack.getLiteralPath(), vr.isOk(), I18nConstants.CONCEPTMAP_GROUP_TARGET_CODE_INVALID_VS, c, ctxt.targetScope.vs.getVersionedUrl())) {
|
||||
ok = (ctxt.target.cs.getContent() != CodeSystemContentMode.COMPLETE) && ok;
|
||||
|
|
|
@ -767,6 +767,7 @@ public class QuestionnaireValidator extends BaseValidator {
|
|||
}
|
||||
}
|
||||
|
||||
if (!noTerminologyChecks) {
|
||||
long t = System.nanoTime();
|
||||
ValidationContextCarrier vc = makeValidationContext(errors, qSrc);
|
||||
ValidationResult res = context.validateCode(new ValidationOptions(FhirPublication.R5, stack.getWorkingLang()), c, vs, vc);
|
||||
|
@ -782,6 +783,7 @@ public class QuestionnaireValidator extends BaseValidator {
|
|||
} else if (res.getMessage() != null) {
|
||||
super.addValidationMessage(errors, NO_RULE_DATE, IssueType.INFORMATIONAL, value.line(), value.col(), stack.getLiteralPath(), res.getMessage(), res.getSeverity() == null ? IssueSeverity.INFORMATION : res.getSeverity(), Source.TerminologyEngine, null);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, value.line(), value.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_CODING, e.getMessage());
|
||||
}
|
||||
|
|
|
@ -98,9 +98,11 @@ public class ValueSetValidator extends BaseValidator {
|
|||
public PropertyFilterType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public EnumSet<PropertyOperation> getOps() {
|
||||
return ops;
|
||||
}
|
||||
|
||||
public CodeValidationRule getCodeValidation() {
|
||||
return codeValidation;
|
||||
}
|
||||
|
@ -316,6 +318,7 @@ public class ValueSetValidator extends BaseValidator {
|
|||
}
|
||||
}
|
||||
|
||||
if (!noTerminologyChecks) {
|
||||
boolean systemOk = true;
|
||||
int cc = 0;
|
||||
List<VSCodingValidationRequest> batch = new ArrayList<>();
|
||||
|
@ -347,6 +350,7 @@ public class ValueSetValidator extends BaseValidator {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int cf = 0;
|
||||
for (Element filter : filters) {
|
||||
ok = validateValueSetIncludeFilter(errors, filter, stack.push(filter, cf, null, null), system, version, cs, csChecker) & ok;
|
||||
|
@ -386,6 +390,7 @@ public class ValueSetValidator extends BaseValidator {
|
|||
String display = concept.getChildValue("display");
|
||||
slv.checkConcept(code, display);
|
||||
|
||||
if (!!noTerminologyChecks) {
|
||||
if (version == null) {
|
||||
ValidationResult vv = context.validateCode(ValidationOptions.defaults().withExampleOK(), new Coding(system, code, null), null);
|
||||
if (vv.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) {
|
||||
|
@ -419,6 +424,7 @@ public class ValueSetValidator extends BaseValidator {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -517,7 +523,7 @@ public class ValueSetValidator extends BaseValidator {
|
|||
ok = rule(errors, "2024-03-09", IssueType.INVALID, stack,
|
||||
value.trim().equals(value),
|
||||
I18nConstants.VALUESET_BAD_FILTER_VALUE_CODE, property, value) && ok;
|
||||
if (rules.getCodeValidation() == CodeValidationRule.Error || rules.getCodeValidation() == CodeValidationRule.Warning) {
|
||||
if (!noTerminologyChecks && (rules.getCodeValidation() == CodeValidationRule.Error || rules.getCodeValidation() == CodeValidationRule.Warning)) {
|
||||
ValidationResult vr = context.validateCode(baseOptions, system, version, value, null);
|
||||
if (rules.getCodeValidation() == CodeValidationRule.Error) {
|
||||
ok = rule(errors, "2024-03-09", IssueType.INVALID, stack.getLiteralPath(), vr.isOk(), rules.isChange() ? I18nConstants.VALUESET_BAD_FILTER_VALUE_VALID_CODE_CHANGE : I18nConstants.VALUESET_BAD_FILTER_VALUE_VALID_CODE, property, value, system, vr.getMessage()) && ok;
|
||||
|
@ -557,7 +563,7 @@ public class ValueSetValidator extends BaseValidator {
|
|||
Coding code = Coding.fromLiteral(value);
|
||||
if (code == null) {
|
||||
ok = rule(errors, "2024-03-09", IssueType.INVALID, stack, false, I18nConstants.VALUESET_BAD_FILTER_VALUE_CODED, property, value) && ok;
|
||||
} else {
|
||||
} else if (!noTerminologyChecks) {
|
||||
ValidationResult vr = context.validateCode(baseOptions, code, null);
|
||||
ok = rule(errors, "2024-03-09", IssueType.INVALID, stack, vr.isOk(), I18nConstants.VALUESET_BAD_FILTER_VALUE_CODED_INVALID, property, value, vr.getMessage()) && ok;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue