diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java index 5b529d4eb..ea7759895 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java @@ -69,7 +69,6 @@ import org.hl7.fhir.r5.utils.UserDataNames; import org.hl7.fhir.r5.utils.XVerExtensionManager; import org.hl7.fhir.r5.utils.XVerExtensionManager.XVerExtensionStatus; import org.hl7.fhir.r5.utils.validation.IMessagingServices; -import org.hl7.fhir.r5.utils.validation.IResourceValidator; import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor; import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher; import org.hl7.fhir.r5.utils.validation.ValidatorSession; @@ -281,7 +280,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi protected String urlRegex; - private boolean suppressMsg(String path, String theMessage) { + protected boolean isSuppressedValidationMessage(String path, String theMessage) { if (policyAdvisor == null) { return false; } else { @@ -290,7 +289,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi } protected boolean fail(List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) { - if (!thePass && doingErrors() && !suppressMsg(path, theMessage)) { + if (!thePass && doingErrors() && !isSuppressedValidationMessage(path, theMessage)) { String msg = context.formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, ruleDate, type, line, col, path, msg, IssueSeverity.FATAL, theMessage); } @@ -310,7 +309,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean hint(List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, String msg) { - if (!thePass && doingHints() && !suppressMsg(path, msg)) { + if (!thePass && doingHints() && !isSuppressedValidationMessage(path, msg)) { String message = context.formatMessage(msg); addValidationMessage(errors, ruleDate, type, line, col, path, message, IssueSeverity.INFORMATION, msg); } @@ -325,7 +324,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean hintInv(List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, String msg, String invId) { - if (!thePass && doingHints() && !suppressMsg(path, invId)) { + if (!thePass && doingHints() && !isSuppressedValidationMessage(path, invId)) { String message = context.formatMessage(msg); addValidationMessage(errors, ruleDate, type, line, col, path, message, IssueSeverity.INFORMATION, msg).setInvId(invId); } @@ -364,7 +363,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean hint(List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) { - if (!thePass && doingHints() && !suppressMsg(path, theMessage)) { + if (!thePass && doingHints() && !isSuppressedValidationMessage(path, theMessage)) { String message = context.formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, ruleDate, type, line, col, path, message, IssueSeverity.INFORMATION, theMessage); } @@ -372,7 +371,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi } protected boolean hintPlural(List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, int num, String theMessage, Object... theMessageArguments) { - if (!thePass && doingHints() && !suppressMsg(path, theMessage)) { + if (!thePass && doingHints() && !isSuppressedValidationMessage(path, theMessage)) { String message = context.formatMessagePlural(num, theMessage, theMessageArguments); addValidationMessage(errors, ruleDate, type, line, col, path, message, IssueSeverity.INFORMATION, theMessage); } @@ -385,7 +384,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi } protected boolean txHint(List errors, String ruleDate, String txLink, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) { - if (!thePass && doingHints() && !suppressMsg(path, theMessage)) { + if (!thePass && doingHints() && !isSuppressedValidationMessage(path, theMessage)) { String message = context.formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, ruleDate, type, line, col, path, message, IssueSeverity.INFORMATION, Source.TerminologyEngine, theMessage).setTxLink(txLink); } @@ -400,7 +399,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean hint(List errors, String ruleDate, IssueType type, List pathParts, boolean thePass, String theMessage, Object... theMessageArguments) { - if (!thePass && doingHints() && !suppressMsg(CommaSeparatedStringBuilder.join(".", pathParts), theMessage)) { + if (!thePass && doingHints() && !isSuppressedValidationMessage(CommaSeparatedStringBuilder.join(".", pathParts), theMessage)) { String path = toPath(pathParts); String message = context.formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, ruleDate, type, -1, -1, path, message, IssueSeverity.INFORMATION, theMessage); @@ -416,7 +415,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean hint(List errors, String ruleDate, IssueType type, String path, boolean thePass, String theMessage, Object... theMessageArguments) { - if (!thePass && doingHints() && !suppressMsg(path, theMessage)) { + if (!thePass && doingHints() && !isSuppressedValidationMessage(path, theMessage)) { String message = context.formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, ruleDate, type, -1, -1, path, message, IssueSeverity.INFORMATION, null); } @@ -431,7 +430,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean rule(List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) { - if (!thePass && doingErrors() && !suppressMsg(path, theMessage)) { + if (!thePass && doingErrors() && !isSuppressedValidationMessage(path, theMessage)) { String message = context.formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, ruleDate, type, line, col, path, message, IssueSeverity.ERROR, theMessage); } @@ -439,7 +438,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi } protected boolean ruleInv(List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, String theMessage, String invId, Object... theMessageArguments) { - if (!thePass && doingErrors() && !suppressMsg(path, theMessage)) { + if (!thePass && doingErrors() && !isSuppressedValidationMessage(path, theMessage)) { String message = context.formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, ruleDate, type, line, col, path, message, IssueSeverity.ERROR, invId).setInvId(invId); } @@ -447,7 +446,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi } protected boolean rule(List errors, String ruleDate, IssueType type, NodeStack stack, boolean thePass, String theMessage, Object... theMessageArguments) { - if (!thePass && doingErrors() && !suppressMsg(stack.getLiteralPath(), theMessage)) { + if (!thePass && doingErrors() && !isSuppressedValidationMessage(stack.getLiteralPath(), theMessage)) { String message = context.formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, ruleDate, type, stack.line(), stack.col(), stack.getLiteralPath(), message, IssueSeverity.ERROR, theMessage); } @@ -459,7 +458,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi } protected boolean rulePlural(List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, int num, String theMessage, Object... theMessageArguments) { - if (!thePass && doingErrors() && !suppressMsg(path, theMessage)) { + if (!thePass && doingErrors() && !isSuppressedValidationMessage(path, theMessage)) { String message = context.formatMessagePlural(num, theMessage, theMessageArguments); addValidationMessage(errors, ruleDate, type, line, col, path, message, IssueSeverity.ERROR, theMessage); } @@ -467,7 +466,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi } protected boolean txRule(List errors, String ruleDate, String txLink, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) { - if (!thePass && doingErrors() && !suppressMsg(path, theMessage)) { + if (!thePass && doingErrors() && !isSuppressedValidationMessage(path, theMessage)) { String message = context.formatMessage(theMessage, theMessageArguments); ValidationMessage vm = new ValidationMessage(Source.TerminologyEngine, type, line, col, path, message, IssueSeverity.ERROR).setMessageId(idForMessage(theMessage, message)); vm.setRuleDate(ruleDate); @@ -505,7 +504,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean rule(List errors, String ruleDate, IssueType type, List pathParts, boolean thePass, String theMessage, Object... theMessageArguments) { - if (!thePass && doingErrors() && !suppressMsg(CommaSeparatedStringBuilder.join(".", pathParts), theMessage)) { + if (!thePass && doingErrors() && !isSuppressedValidationMessage(CommaSeparatedStringBuilder.join(".", pathParts), theMessage)) { String path = toPath(pathParts); String message = context.formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, ruleDate, type, -1, -1, path, message, IssueSeverity.ERROR, theMessage); @@ -523,7 +522,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi protected boolean rule(List errors, String ruleDate, IssueType type, String path, boolean thePass, String theMessage, Object... theMessageArguments) { - if (!thePass && doingErrors() && !suppressMsg(path, theMessage)) { + if (!thePass && doingErrors() && !isSuppressedValidationMessage(path, theMessage)) { String message = context.formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, ruleDate, type, -1, -1, path, message, IssueSeverity.ERROR, theMessage); } @@ -531,7 +530,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi } protected boolean rulePlural(List errors, String ruleDate, IssueType type, String path, boolean thePass, int num, String theMessage, Object... theMessageArguments) { - if (!thePass && doingErrors() && !suppressMsg(path, theMessage)) { + if (!thePass && doingErrors() && !isSuppressedValidationMessage(path, theMessage)) { String message = context.formatMessagePlural(num, theMessage, theMessageArguments); addValidationMessage(errors, ruleDate, type, -1, -1, path, message, IssueSeverity.ERROR, theMessage); } @@ -597,7 +596,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean warning(List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) { - if (!thePass && doingWarnings() && !suppressMsg(path, msg)) { + if (!thePass && doingWarnings() && !isSuppressedValidationMessage(path, msg)) { String nmsg = context.formatMessage(msg, theMessageArguments); IssueSeverity severity = IssueSeverity.WARNING; addValidationMessage(errors, ruleDate, type, line, col, path, nmsg, severity, msg); @@ -607,7 +606,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi } protected boolean warning(List errors, String ruleDate, IssueType type, int line, int col, String path, String id, boolean thePass, String msg, Object... theMessageArguments) { - if (!thePass && doingWarnings() && !suppressMsg(path, msg)) { + if (!thePass && doingWarnings() && !isSuppressedValidationMessage(path, msg)) { String nmsg = context.formatMessage(msg, theMessageArguments); IssueSeverity severity = IssueSeverity.WARNING; addValidationMessage(errors, ruleDate, type, line, col, path, nmsg, severity, id); @@ -617,7 +616,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi } protected boolean warningInv(List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, String msg, String invId, Object... theMessageArguments) { - if (!thePass && doingWarnings() && !suppressMsg(path, invId)) { + if (!thePass && doingWarnings() && !isSuppressedValidationMessage(path, invId)) { String nmsg = context.formatMessage(msg, theMessageArguments); IssueSeverity severity = IssueSeverity.WARNING; String id = idForMessage(msg, nmsg); @@ -636,7 +635,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi } protected boolean warningPlural(List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, int num, String msg, Object... theMessageArguments) { - if (!thePass && doingWarnings() && !suppressMsg(path, msg)) { + if (!thePass && doingWarnings() && !isSuppressedValidationMessage(path, msg)) { String nmsg = context.formatMessagePlural(num, msg, theMessageArguments); IssueSeverity severity = IssueSeverity.WARNING; addValidationMessage(errors, ruleDate, type, line, col, path, nmsg, severity, msg); @@ -678,7 +677,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean txWarning(List errors, String ruleDate, String txLink, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) { - if (!thePass && doingWarnings() && !suppressMsg(path, msg)) { + if (!thePass && doingWarnings() && !isSuppressedValidationMessage(path, msg)) { String nmsg = context.formatMessage(msg, theMessageArguments); ValidationMessage vmsg = new ValidationMessage(Source.TerminologyEngine, type, line, col, path, nmsg, IssueSeverity.WARNING).setTxLink(txLink).setMessageId(idForMessage(msg, nmsg)); vmsg.setRuleDate(ruleDate); @@ -691,30 +690,23 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi } /** - * Test a rule and add a {@link IssueSeverity#WARNING} validation message if the validation fails - * - * @param thePass - * Set this parameter to false if the validation does not pass + * @param thePass Set this parameter to false if the validation does not pass * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ - protected ValidationMessage txIssue(List errors, String ruleDate, String txLink, int line, int col, String path, OperationOutcomeIssueComponent issue) { + protected ValidationMessage buildValidationMessage(String txLink, int line, int col, String path, OperationOutcomeIssueComponent issue) { if (issue.hasLocation() && issue.getExpressionOrLocation().get(0).getValue().contains(".")) { path = path + dropHead(issue.getExpressionOrLocation().get(0).getValue()); } IssueType code = IssueType.fromCode(issue.getCode().toCode()); IssueSeverity severity = IssueSeverity.fromCode(issue.getSeverity().toCode()); - ValidationMessage vmsg = new ValidationMessage(Source.TerminologyEngine, code, line, col, path, issue.getDetails().getText(), severity).setTxLink(txLink); + ValidationMessage validationMessage = new ValidationMessage(Source.TerminologyEngine, code, line, col, path, issue.getDetails().getText(), severity).setTxLink(txLink); if (issue.getExtensionString(ToolingExtensions.EXT_ISSUE_SERVER) != null) { - vmsg.setServer(issue.getExtensionString(ToolingExtensions.EXT_ISSUE_SERVER).replace("local.fhir.org", "tx-dev.fhir.org")); + validationMessage.setServer(issue.getExtensionString(ToolingExtensions.EXT_ISSUE_SERVER).replace("local.fhir.org", "tx-dev.fhir.org")); } if (issue.getExtensionString(ToolingExtensions.EXT_ISSUE_MSG_ID) != null) { - vmsg.setMessageId(issue.getExtensionString(ToolingExtensions.EXT_ISSUE_MSG_ID)); + validationMessage.setMessageId(issue.getExtensionString(ToolingExtensions.EXT_ISSUE_MSG_ID)); } - - if (!suppressMsg(path, vmsg.getMessageId())) { - errors.add(vmsg); - } - return vmsg; + return validationMessage; } private String dropHead(String value) { @@ -729,7 +721,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean txWarningForLaterRemoval(Object location, List errors, String ruleDate, String txLink, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) { - if (!thePass && doingWarnings() && !suppressMsg(path, msg)) { + if (!thePass && doingWarnings() && !isSuppressedValidationMessage(path, msg)) { String nmsg = context.formatMessage(msg, theMessageArguments); ValidationMessage vmsg = new ValidationMessage(Source.TerminologyEngine, type, line, col, path, nmsg, IssueSeverity.WARNING).setTxLink(txLink).setMessageId(msg); vmsg.setRuleDate(ruleDate); @@ -758,7 +750,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi } protected boolean warningOrError(boolean isError, List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) { - if (!thePass && !suppressMsg(path, msg)) { + if (!thePass && !isSuppressedValidationMessage(path, msg)) { String nmsg = context.formatMessage(msg, theMessageArguments); IssueSeverity lvl = isError ? IssueSeverity.ERROR : IssueSeverity.WARNING; if (doingLevel(lvl)) { @@ -774,7 +766,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi } protected boolean hintOrError(boolean isError, List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) { - if (!thePass && !suppressMsg(path, msg)) { + if (!thePass && !isSuppressedValidationMessage(path, msg)) { String nmsg = context.formatMessage(msg, theMessageArguments); IssueSeverity lvl = isError ? IssueSeverity.ERROR : IssueSeverity.INFORMATION; if (doingLevel(lvl)) { @@ -793,7 +785,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean warning(List errors, String ruleDate, IssueType type, List pathParts, boolean thePass, String theMessage, Object... theMessageArguments) { - if (!thePass && doingWarnings() && !suppressMsg(CommaSeparatedStringBuilder.join(".", pathParts), theMessage)) { + if (!thePass && doingWarnings() && !isSuppressedValidationMessage(CommaSeparatedStringBuilder.join(".", pathParts), theMessage)) { String path = toPath(pathParts); String message = context.formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, ruleDate, type, -1, -1, path, message, IssueSeverity.WARNING, theMessage); @@ -809,7 +801,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean warning(List errors, String ruleDate, IssueType type, String path, boolean thePass, String msg, Object... theMessageArguments) { - if (!thePass && doingWarnings() && !suppressMsg(path, msg)) { + if (!thePass && doingWarnings() && !isSuppressedValidationMessage(path, msg)) { String message = context.formatMessage(msg, theMessageArguments); addValidationMessage(errors, ruleDate, type, -1, -1, path, message, IssueSeverity.WARNING, null); } @@ -824,7 +816,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean warningOrHint(List errors, String ruleDate, IssueType type, String path, boolean thePass, boolean warning, String msg, Object... theMessageArguments) { - if (!thePass && !suppressMsg(path, msg)) { + if (!thePass && !isSuppressedValidationMessage(path, msg)) { String message = context.formatMessage(msg, theMessageArguments); IssueSeverity lvl = warning ? IssueSeverity.WARNING : IssueSeverity.INFORMATION; if (doingLevel(lvl)) { @@ -842,7 +834,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean warningHtml(List errors, String ruleDate, IssueType type, String path, boolean thePass, String msg, String html) { - if (!thePass && doingWarnings() && !suppressMsg(path, msg)) { + if (!thePass && doingWarnings() && !isSuppressedValidationMessage(path, msg)) { addValidationMessage(errors, ruleDate, type, path, msg, html, IssueSeverity.WARNING, null); } return thePass; @@ -856,7 +848,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean warningHtml(List errors, String ruleDate, IssueType type, String path, boolean thePass, String msg, String html, Object... theMessageArguments) { - if (!thePass && doingWarnings() && !suppressMsg(path, msg)) { + if (!thePass && doingWarnings() && !isSuppressedValidationMessage(path, msg)) { String nmsg = context.formatMessage(msg, theMessageArguments); addValidationMessage(errors, ruleDate, type, path, nmsg, html, IssueSeverity.WARNING, msg); } @@ -872,7 +864,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean suppressedwarning(List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) { - if (!thePass && doingWarnings() && !suppressMsg(path, msg)) { + if (!thePass && doingWarnings() && !isSuppressedValidationMessage(path, msg)) { String nmsg = context.formatMessage(msg, theMessageArguments); addValidationMessage(errors, ruleDate, type, line, col, path, nmsg, IssueSeverity.INFORMATION, msg); } @@ -888,7 +880,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean suppressedwarning(List errors, String ruleDate, IssueType type, List pathParts, boolean thePass, String theMessage, Object... theMessageArguments) { - if (!thePass && doingWarnings() && !suppressMsg(CommaSeparatedStringBuilder.join(".", pathParts), theMessage)) { + if (!thePass && doingWarnings() && !isSuppressedValidationMessage(CommaSeparatedStringBuilder.join(".", pathParts), theMessage)) { String path = toPath(pathParts); String message = context.formatMessage(theMessage, theMessageArguments); addValidationMessage(errors, ruleDate, type, -1, -1, path, message, IssueSeverity.INFORMATION, theMessage); @@ -943,7 +935,7 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ protected boolean suppressedwarning(List errors, String ruleDate, IssueType type, String path, boolean thePass, String msg, String html, Object... theMessageArguments) { - if (!thePass && doingWarnings() && !suppressMsg(path, msg)) { + if (!thePass && doingWarnings() && !isSuppressedValidationMessage(path, msg)) { String nmsg = context.formatMessage(msg, theMessageArguments); addValidationMessage(errors, ruleDate, type, path, nmsg, html, IssueSeverity.INFORMATION, msg); } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java index 8576bfaf9..512c2bc97 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java @@ -1118,7 +1118,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat timeTracker.tx(t, "vc "+system+"#"+code+" '"+display+"'"); if (s == null) return true; - ok = processTxIssues(errors, s, element, path, false, null, null) & ok; + ok = calculateSeverityForIssuesAndUpdateErrors(errors, s, element, path, false, null, null) & ok; if (s.isOk()) { if (s.getMessage() != null && !s.messageIsInIssues()) { @@ -1375,7 +1375,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (cc.hasCoding()) { long t = System.nanoTime(); ValidationResult vr = checkCodeOnServer(stack, null, cc); - bh.see(processTxIssues(errors, vr, element, path, false, null, null)); + bh.see(calculateSeverityForIssuesAndUpdateErrors(errors, vr, element, path, false, null, null)); timeTracker.tx(t, "vc " + cc.toString()); } } catch (CheckCodeOnServerException e) { @@ -1620,7 +1620,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } else { checked.set(true); ValidationResult vr = checkCodeOnServer(stack, valueset, cc); - bh.see(processTxIssues(errors, vr, element, path, false, vsRef, strength)); + bh.see(calculateSeverityForIssuesAndUpdateErrors(errors, vr, element, path, false, vsRef, strength)); if (!vr.isOk()) { bindingsOk = false; if (vr.getErrorClass() != null && vr.getErrorClass() == TerminologyServiceErrorClass.NOSERVICE) { @@ -1715,80 +1715,82 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat // } // } - private boolean processTxIssues(List errors, ValidationResult vr, Element element, String path, boolean ignoreCantInfer, String vsurl, BindingStrength bs) { - boolean ok = true; - if (vr != null) { - for (OperationOutcomeIssueComponent iss : vr.getIssues()) { - Optional processedTxIssue = processTxIssue(iss, ignoreCantInfer, bs); - if (processedTxIssue.isPresent()) { - var vmsg = txIssue(errors, null, vr.getTxLink(), element.line(), element.col(), path, processedTxIssue.get()); - if (vmsg.isError()) { - ok = false; + private boolean calculateSeverityForIssuesAndUpdateErrors(List errors, ValidationResult validationResult, Element element, String path, boolean ignoreCantInfer, String vsurl, BindingStrength bindingStrength) { + boolean noErrorsFound = true; + if (validationResult != null) { + for (OperationOutcomeIssueComponent issue : validationResult.getIssues()) { + if (!isIgnoredTxIssueType(issue, ignoreCantInfer)) { + OperationOutcomeIssueComponent issueWithCalculatedSeverity = getTxIssueWithCalculatedSeverity(issue, ignoreCantInfer, bindingStrength); + var validationMessage = buildValidationMessage(validationResult.getTxLink(), element.line(), element.col(), path, issueWithCalculatedSeverity); + if (!isSuppressedValidationMessage(path, validationMessage.getMessageId())) { + errors.add(validationMessage); + if (validationMessage.isError()) { + noErrorsFound = false; + } } } } } - return ok; + return noErrorsFound; } - private Optional processTxIssue(OperationOutcomeIssueComponent iss, boolean ignoreCantInfer, BindingStrength bs) { - if (iss.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "not-in-vs")) - { - return Optional.empty(); + private boolean isIgnoredTxIssueType(OperationOutcomeIssueComponent issueComponent, boolean ignoreCantInfer) { + if (issueComponent.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "not-in-vs")) { + return true; } - if (iss.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "this-code-not-in-vs")) - { - return Optional.empty(); + if (issueComponent.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "this-code-not-in-vs")) { + return true; } - if (ignoreCantInfer || iss.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "cannot-infer")) - { - return Optional.empty(); + if (ignoreCantInfer || issueComponent.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "cannot-infer")) { + return true; } + return false; + } - OperationOutcomeIssueComponent i = iss.copy(); - if (i.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "not-found")) { - String msg = iss.getDetails().getText(); - boolean isHL7 = msg == null ? false : msg.contains("http://hl7.org/fhir") || msg.contains("http://terminology.hl7.org"); - org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity notFoundLevel = null; - String notFoundNote = null; - if (bs == null) { - notFoundLevel = org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.WARNING; - notFoundNote = null; // "binding=null"; - } else if (bs == BindingStrength.REQUIRED && isHL7) { - notFoundLevel = org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.ERROR; - notFoundNote = "error because this is a required binding to an HL7 code system"; - } else if (bs == BindingStrength.REQUIRED && unknownCodeSystemsCauseErrors) { - notFoundLevel = org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.ERROR; - notFoundNote = "error because this is a required binding"; - } else if (bs == BindingStrength.REQUIRED) { - notFoundLevel = org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.WARNING; - notFoundNote = null; // "binding=required"; - } else if (bs == BindingStrength.EXTENSIBLE) { - notFoundLevel = org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.WARNING; - notFoundNote = null; // "binding=extensible"; - } else { - notFoundLevel = org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.WARNING; - notFoundNote = null; // "binding="+bs.toCode(); - } - if (notFoundLevel != null && i.getSeverity().isHigherThan(notFoundLevel)) { // && (vsurl != null && i.getDetails().getText().contains(vsurl))) { - i.setSeverity(notFoundLevel); - if (notFoundNote != null) { - i.getDetails().setText(i.getDetails().getText()+" ("+notFoundNote+")"); - } + private OperationOutcomeIssueComponent getTxIssueWithCalculatedSeverity(OperationOutcomeIssueComponent issueComponent, boolean ignoreCantInfer, BindingStrength bindingStrength) { + OperationOutcomeIssueComponent outIssueComponent = issueComponent.copy(); + if (outIssueComponent.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "not-found")) { + String text = issueComponent.getDetails().getText(); + boolean isHL7 = text == null ? false : text.contains("http://hl7.org/fhir") || text.contains("http://terminology.hl7.org"); + org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity notFoundLevel = null; + String notFoundNote = null; + if (bindingStrength == null) { + notFoundLevel = org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.WARNING; + notFoundNote = null; // "binding=null"; + } else if (bindingStrength == BindingStrength.REQUIRED && isHL7) { + notFoundLevel = org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.ERROR; + notFoundNote = "error because this is a required binding to an HL7 code system"; + } else if (bindingStrength == BindingStrength.REQUIRED && unknownCodeSystemsCauseErrors) { + notFoundLevel = org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.ERROR; + notFoundNote = "error because this is a required binding"; + } else if (bindingStrength == BindingStrength.REQUIRED) { + notFoundLevel = org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.WARNING; + notFoundNote = null; // "binding=required"; + } else if (bindingStrength == BindingStrength.EXTENSIBLE) { + notFoundLevel = org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.WARNING; + notFoundNote = null; // "binding=extensible"; + } else { + notFoundLevel = org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.WARNING; + notFoundNote = null; // "binding="+bs.toCode(); + } + if (notFoundLevel != null && outIssueComponent.getSeverity().isHigherThan(notFoundLevel)) { // && (vsurl != null && i.getDetails().getText().contains(vsurl))) { + outIssueComponent.setSeverity(notFoundLevel); + if (notFoundNote != null) { + outIssueComponent.getDetails().setText(outIssueComponent.getDetails().getText() + " (" + notFoundNote + ")"); } } - if (baseOptions.isDisplayWarningMode() && i.getSeverity() == org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.ERROR && i.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "invalid-display")) { - i.setSeverity(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.WARNING); - } - return Optional.of(i); - + } + if (outIssueComponent.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "invalid-display") && baseOptions.isDisplayWarningMode() && outIssueComponent.getSeverity() == org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.ERROR) { + outIssueComponent.setSeverity(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.WARNING); + } + return outIssueComponent; } public boolean checkBindings(List errors, String path, Element element, NodeStack stack, ValueSet valueset, Coding nextCoding) { boolean ok = true; if (isNotBlank(nextCoding.getCode()) && isNotBlank(nextCoding.getSystem()) && context.supportsSystem(nextCoding.getSystem(), baseOptions.getFhirVersion())) { ValidationResult vr = checkCodeOnServer(stack, valueset, nextCoding); - ok = processTxIssues(errors, vr, element, path, false, null, null) && ok; + ok = calculateSeverityForIssuesAndUpdateErrors(errors, vr, element, path, false, null, null) && ok; if (vr.getSeverity() != null && !vr.messageIsInIssues()) { if (vr.getSeverity() == IssueSeverity.INFORMATION) { @@ -1919,7 +1921,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (strength == BindingStrength.REQUIRED) { removeTrackedMessagesForLocation(errors, element, path); } - ok = processTxIssues(errors, vr, element, path, false, vsRef, strength) && ok; + ok = calculateSeverityForIssuesAndUpdateErrors(errors, vr, element, path, false, vsRef, strength) && ok; timeTracker.tx(t, "vc "+system+"#"+code+" '"+display+"'"); if (vr != null && !vr.isOk()) { if (vr.IsNoService()) @@ -2064,7 +2066,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat try { long t = System.nanoTime(); ValidationResult vr = checkCodeOnServer(stack, valueset, cc); - ok = processTxIssues(errors, vr, element, path, false, maxVSUrl, null) && ok; + ok = calculateSeverityForIssuesAndUpdateErrors(errors, vr, element, path, false, maxVSUrl, null) && ok; timeTracker.tx(t, "vc "+cc.toString()); if (!vr.isOk()) { if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) @@ -2103,7 +2105,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat try { long t = System.nanoTime(); ValidationResult vr = checkCodeOnServer(stack, valueset, c); - ok = processTxIssues(errors, vr, element, path, false, maxVSUrl, null) && ok; + ok = calculateSeverityForIssuesAndUpdateErrors(errors, vr, element, path, false, maxVSUrl, null) && ok; timeTracker.tx(t, "vc "+c.getSystem()+"#"+c.getCode()+" '"+c.getDisplay()+"'"); if (!vr.isOk()) { @@ -2134,7 +2136,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat try { long t = System.nanoTime(); ValidationResult vr = checkCodeOnServer(stack, valueset, value, baseOptions); - ok = processTxIssues(errors, vr, element, path, false, maxVSUrl, null) && ok; + ok = calculateSeverityForIssuesAndUpdateErrors(errors, vr, element, path, false, maxVSUrl, null) && ok; timeTracker.tx(t, "vc "+value); if (!vr.isOk()) { if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) @@ -2269,7 +2271,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat checked.set(true); vr = checkCodeOnServer(stack, valueset, c); } - ok = processTxIssues(errors, vr, element, path, strength == BindingStrength.EXTENSIBLE, vsRef, strength) && ok; + ok = calculateSeverityForIssuesAndUpdateErrors(errors, vr, element, path, strength == BindingStrength.EXTENSIBLE, vsRef, strength) && ok; timeTracker.tx(t, "vc "+c.getSystem()+"#"+c.getCode()+" '"+c.getDisplay()+"'"); if (strength == BindingStrength.REQUIRED) { @@ -3744,7 +3746,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } vr = checkCodeOnServer(stack, vs, value, options); } - ok = processTxIssues(errors, vr, element, path, binding.getStrength() != BindingStrength.REQUIRED, binding.getValueSet(), binding.getStrength()) && ok; + ok = calculateSeverityForIssuesAndUpdateErrors(errors, vr, element, path, binding.getStrength() != BindingStrength.REQUIRED, binding.getValueSet(), binding.getStrength()) && ok; timeTracker.tx(t, "vc "+value+""); if (binding.getStrength() == BindingStrength.REQUIRED) {