make HL7 WG validation rule publication dependent

This commit is contained in:
Grahame Grieve 2024-11-19 12:47:04 +11:00
parent a0b87c7947
commit d7d2ea50f3
7 changed files with 97 additions and 75 deletions

View File

@ -176,6 +176,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
protected XVerExtensionManager xverManager; protected XVerExtensionManager xverManager;
protected IValidatorResourceFetcher fetcher; protected IValidatorResourceFetcher fetcher;
protected IValidationPolicyAdvisor policyAdvisor; protected IValidationPolicyAdvisor policyAdvisor;
protected boolean noTerminologyChecks;
// these two related to removing warnings on extensible bindings in structures that have derivatives that replace their bindings // these two related to removing warnings on extensible bindings in structures that have derivatives that replace their bindings
protected List<TrackedLocationRelatedMessage> trackedMessages = new ArrayList<>(); protected List<TrackedLocationRelatedMessage> trackedMessages = new ArrayList<>();
@ -235,6 +236,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
this.baseOptions = parent.baseOptions; this.baseOptions = parent.baseOptions;
this.fetcher = parent.fetcher; this.fetcher = parent.fetcher;
this.policyAdvisor = parent.policyAdvisor; this.policyAdvisor = parent.policyAdvisor;
this.noTerminologyChecks = parent.noTerminologyChecks;
} }
private boolean doingLevel(IssueSeverity error) { private boolean doingLevel(IssueSeverity error) {

View File

@ -8,6 +8,7 @@ import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.utils.XVerExtensionManager; import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.ValidatorSession; import org.hl7.fhir.r5.utils.validation.ValidatorSession;
import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.i18n.I18nConstants; import org.hl7.fhir.utilities.i18n.I18nConstants;
import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; 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) { public PropertyValidationRules rulesForFilter(String property, EnumSet<PropertyOperation> ops) {
switch (property) { 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 "concept" :
case "code" : return new PropertyValidationRules(PropertyFilterType.Code, CodeValidationRule.Error, addToOps(ops, PropertyOperation.Equals, PropertyOperation.RegEx)); 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 "status" : return new PropertyValidationRules(PropertyFilterType.Code, CodeValidationRule.None, ops);
case "inactive" : return new PropertyValidationRules(PropertyFilterType.Boolean,null, ops); case "inactive" : return new PropertyValidationRules(PropertyFilterType.Boolean,null, ops);
case "effectiveDate" : return new PropertyValidationRules(PropertyFilterType.DateTime, null, ops); case "effectiveDate" : return new PropertyValidationRules(PropertyFilterType.DateTime, null, ops);

View File

@ -565,7 +565,6 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
private boolean errorForUnknownProfiles; private boolean errorForUnknownProfiles;
private boolean noInvariantChecks; private boolean noInvariantChecks;
private boolean wantInvariantInMessage; private boolean wantInvariantInMessage;
private boolean noTerminologyChecks;
private boolean hintAboutNonMustSupport; private boolean hintAboutNonMustSupport;
private boolean showMessagesFromReferences; private boolean showMessagesFromReferences;
private String validationLanguage; 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) { if (wg != null) {
HL7WorkGroup wgd = HL7WorkGroups.find(wg); 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)) { if (rule(errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), wgd != null, I18nConstants.VALIDATION_HL7_WG_UNKNOWN, wg)) {

View File

@ -638,7 +638,7 @@ public class CodeSystemValidator extends BaseValidator {
private boolean validateSupplementConcept(List<ValidationMessage> errors, Element concept, NodeStack stack, String supp, ValidationOptions options) { private boolean validateSupplementConcept(List<ValidationMessage> errors, Element concept, NodeStack stack, String supp, ValidationOptions options) {
String code = concept.getChildValue("code"); String code = concept.getChildValue("code");
if (!Utilities.noString(code)) { if (!Utilities.noString(code) && !noTerminologyChecks) {
var canonical = new CanonicalPair(supp); var canonical = new CanonicalPair(supp);
org.hl7.fhir.r5.terminologies.utilities.ValidationResult res = context.validateCode(options, canonical.getUrl(), canonical.getVersion(), code, null); 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); return rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), res.isOk(), I18nConstants.CODESYSTEM_CS_SUPP_INVALID_CODE, supp, code);

View File

@ -161,7 +161,7 @@ public class ConceptMapValidator extends BaseValidator {
if (!batch.isEmpty()) { if (!batch.isEmpty()) {
if (batch.size() > TOO_MANY_CODES_TO_VALIDATE) { 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; 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 { try {
long t = System.currentTimeMillis(); long t = System.currentTimeMillis();
context.validateCodeBatch(ValidationOptions.defaults(), batch, null); context.validateCodeBatch(ValidationOptions.defaults(), batch, null);
@ -313,7 +313,7 @@ public class ConceptMapValidator extends BaseValidator {
if (display != null) { 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()); 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); 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())) { 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; ok = (ctxt.source.cs.getContent() != CodeSystemContentMode.COMPLETE) & ok;
@ -350,7 +350,7 @@ public class ConceptMapValidator extends BaseValidator {
if (display != null) { 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()); 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); 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())) { 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; ok = (ctxt.target.cs.getContent() != CodeSystemContentMode.COMPLETE) && ok;

View File

@ -767,20 +767,22 @@ public class QuestionnaireValidator extends BaseValidator {
} }
} }
long t = System.nanoTime(); if (!noTerminologyChecks) {
ValidationContextCarrier vc = makeValidationContext(errors, qSrc); long t = System.nanoTime();
ValidationResult res = context.validateCode(new ValidationOptions(FhirPublication.R5, stack.getWorkingLang()), c, vs, vc); ValidationContextCarrier vc = makeValidationContext(errors, qSrc);
timeTracker.tx(t, "vc "+c.getSystem()+"#"+c.getCode()+" '"+c.getDisplay()+"'"); ValidationResult res = context.validateCode(new ValidationOptions(FhirPublication.R5, stack.getWorkingLang()), c, vs, vc);
if (!res.isOk()) { timeTracker.tx(t, "vc "+c.getSystem()+"#"+c.getCode()+" '"+c.getDisplay()+"'");
if (res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) { if (!res.isOk()) {
txWarning(errors, NO_RULE_DATE, res.getTxLink(), IssueType.CODEINVALID, value.line(), value.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_BADOPTION_CS, c.getSystem(), c.getCode(), vs.present()); if (res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) {
} else { txWarning(errors, NO_RULE_DATE, res.getTxLink(), IssueType.CODEINVALID, value.line(), value.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_BADOPTION_CS, c.getSystem(), c.getCode(), vs.present());
ok = txRule(errors, NO_RULE_DATE, res.getTxLink(), IssueType.CODEINVALID, value.line(), value.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_BADOPTION, c.getSystem(), c.getCode(), vs.present(), res.getMessage()) && ok; } else {
ok = txRule(errors, NO_RULE_DATE, res.getTxLink(), IssueType.CODEINVALID, value.line(), value.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_BADOPTION, c.getSystem(), c.getCode(), vs.present(), res.getMessage()) && ok;
}
} else if (res.getSeverity() != null) {
super.addValidationMessage(errors, NO_RULE_DATE, IssueType.CODEINVALID, value.line(), value.col(), stack.getLiteralPath(), res.getMessage(), res.getSeverity(), Source.TerminologyEngine, null);
} 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);
} }
} else if (res.getSeverity() != null) {
super.addValidationMessage(errors, NO_RULE_DATE, IssueType.CODEINVALID, value.line(), value.col(), stack.getLiteralPath(), res.getMessage(), res.getSeverity(), Source.TerminologyEngine, null);
} 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) { } catch (Exception e) {
warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, value.line(), value.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_CODING, e.getMessage()); warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, value.line(), value.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_CODING, e.getMessage());

View File

@ -98,9 +98,11 @@ public class ValueSetValidator extends BaseValidator {
public PropertyFilterType getType() { public PropertyFilterType getType() {
return type; return type;
} }
public EnumSet<PropertyOperation> getOps() { public EnumSet<PropertyOperation> getOps() {
return ops; return ops;
} }
public CodeValidationRule getCodeValidation() { public CodeValidationRule getCodeValidation() {
return codeValidation; return codeValidation;
} }
@ -316,34 +318,36 @@ public class ValueSetValidator extends BaseValidator {
} }
} }
boolean systemOk = true; if (!noTerminologyChecks) {
int cc = 0; boolean systemOk = true;
List<VSCodingValidationRequest> batch = new ArrayList<>(); int cc = 0;
boolean first = true; List<VSCodingValidationRequest> batch = new ArrayList<>();
if (concepts.size() > TOO_MANY_CODES_TO_VALIDATE) { boolean first = true;
hint(errors, "2023-09-06", IssueType.BUSINESSRULE, stack, false, I18nConstants.VALUESET_INC_TOO_MANY_CODES, batch.size()); if (concepts.size() > TOO_MANY_CODES_TO_VALIDATE) {
} else { hint(errors, "2023-09-06", IssueType.BUSINESSRULE, stack, false, I18nConstants.VALUESET_INC_TOO_MANY_CODES, batch.size());
if (((InstanceValidator) parent).isValidateValueSetCodesOnTxServer() && !context.isNoTerminologyServer()) { } else {
try { if (((InstanceValidator) parent).isValidateValueSetCodesOnTxServer() && !context.isNoTerminologyServer()) {
for (Element concept : concepts) { try {
// we treat the first differently because we want to know if the system is worth validating. if it is, then we batch the rest for (Element concept : concepts) {
if (first) { // we treat the first differently because we want to know if the system is worth validating. if it is, then we batch the rest
systemOk = validateValueSetIncludeConcept(errors, concept, stack, stack.push(concept, cc, null, null), system, version, csChecker); if (first) {
first = false; systemOk = validateValueSetIncludeConcept(errors, concept, stack, stack.push(concept, cc, null, null), system, version, csChecker);
} else if (systemOk) { first = false;
batch.add(prepareValidateValueSetIncludeConcept(errors, concept, stack.push(concept, cc, null, null), system, version, csChecker)); } else if (systemOk) {
if (batch.size() > VALIDATION_BATCH_SIZE) { batch.add(prepareValidateValueSetIncludeConcept(errors, concept, stack.push(concept, cc, null, null), system, version, csChecker));
executeValidationBatch(errors, vsid, retired, system, version, batch); if (batch.size() > VALIDATION_BATCH_SIZE) {
batch.clear(); executeValidationBatch(errors, vsid, retired, system, version, batch);
batch.clear();
}
} }
} cc++;
cc++; }
} executeValidationBatch(errors, vsid, retired, system, version, batch);
executeValidationBatch(errors, vsid, retired, system, version, batch); } catch (Exception e) {
} catch (Exception e) { ok = false;
ok = false; VSCodingValidationRequest cv = batch.get(0);
VSCodingValidationRequest cv = batch.get(0); rule(errors, NO_RULE_DATE, IssueType.EXCEPTION, cv.getStack().getLiteralPath(), false, e.getMessage());
rule(errors, NO_RULE_DATE, IssueType.EXCEPTION, cv.getStack().getLiteralPath(), false, e.getMessage()); }
} }
} }
} }
@ -386,36 +390,38 @@ public class ValueSetValidator extends BaseValidator {
String display = concept.getChildValue("display"); String display = concept.getChildValue("display");
slv.checkConcept(code, display); slv.checkConcept(code, display);
if (version == null) { if (!!noTerminologyChecks) {
ValidationResult vv = context.validateCode(ValidationOptions.defaults().withExampleOK(), new Coding(system, code, null), null); if (version == null) {
if (vv.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) { ValidationResult vv = context.validateCode(ValidationOptions.defaults().withExampleOK(), new Coding(system, code, null), null);
if (isExampleUrl(system)) { if (vv.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) {
if (isAllowExamples()) { if (isExampleUrl(system)) {
hint(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stackInc.getLiteralPath(), false, I18nConstants.VALUESET_EXAMPLE_SYSTEM_HINT, system); if (isAllowExamples()) {
hint(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stackInc.getLiteralPath(), false, I18nConstants.VALUESET_EXAMPLE_SYSTEM_HINT, system);
} else {
rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stackInc.getLiteralPath(), false, I18nConstants.VALUESET_EXAMPLE_SYSTEM_ERROR, system);
}
} else { } else {
rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stackInc.getLiteralPath(), false, I18nConstants.VALUESET_EXAMPLE_SYSTEM_ERROR, system); warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stackInc.getLiteralPath(), false, I18nConstants.VALUESET_UNC_SYSTEM_WARNING, system, vv.getMessage());
} }
return false;
} else { } else {
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stackInc.getLiteralPath(), false, I18nConstants.VALUESET_UNC_SYSTEM_WARNING, system, vv.getMessage()); boolean ok = vv.isOk();
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack, ok, I18nConstants.VALUESET_INCLUDE_INVALID_CONCEPT_CODE, system, code, vv.getMessage());
if (vv.getMessage() != null) {
hint(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack, false, vv.getMessage());
}
} }
return false;
} else { } else {
boolean ok = vv.isOk(); ValidationResult vv = context.validateCode(ValidationOptions.defaults().withExampleOK(), new Coding(system, code, null).setVersion(version), null);
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack, ok, I18nConstants.VALUESET_INCLUDE_INVALID_CONCEPT_CODE, system, code, vv.getMessage()); if (vv.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) {
if (vv.getMessage() != null) { warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stackInc.getLiteralPath(), false, I18nConstants.VALUESET_UNC_SYSTEM_WARNING_VER, system+"#"+version, vv.getMessage());
hint(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack, false, vv.getMessage()); return false;
} } else {
} boolean ok = vv.isOk();
} else { warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack, ok, I18nConstants.VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER, system, version, code, vv.getMessage());
ValidationResult vv = context.validateCode(ValidationOptions.defaults().withExampleOK(), new Coding(system, code, null).setVersion(version), null); if (vv.getMessage() != null) {
if (vv.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) { hint(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack, false, vv.getMessage());
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stackInc.getLiteralPath(), false, I18nConstants.VALUESET_UNC_SYSTEM_WARNING_VER, system+"#"+version, vv.getMessage()); }
return false;
} else {
boolean ok = vv.isOk();
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack, ok, I18nConstants.VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER, system, version, code, vv.getMessage());
if (vv.getMessage() != null) {
hint(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack, false, vv.getMessage());
} }
} }
} }
@ -517,7 +523,7 @@ public class ValueSetValidator extends BaseValidator {
ok = rule(errors, "2024-03-09", IssueType.INVALID, stack, ok = rule(errors, "2024-03-09", IssueType.INVALID, stack,
value.trim().equals(value), value.trim().equals(value),
I18nConstants.VALUESET_BAD_FILTER_VALUE_CODE, property, value) && ok; 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); ValidationResult vr = context.validateCode(baseOptions, system, version, value, null);
if (rules.getCodeValidation() == CodeValidationRule.Error) { 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; 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); Coding code = Coding.fromLiteral(value);
if (code == null) { if (code == null) {
ok = rule(errors, "2024-03-09", IssueType.INVALID, stack, false, I18nConstants.VALUESET_BAD_FILTER_VALUE_CODED, property, value) && ok; 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); 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; ok = rule(errors, "2024-03-09", IssueType.INVALID, stack, vr.isOk(), I18nConstants.VALUESET_BAD_FILTER_VALUE_CODED_INVALID, property, value, vr.getMessage()) && ok;
} }