Track and report inactive status when reported from terminology server
This commit is contained in:
parent
2acf546059
commit
497a81a544
|
@ -1197,7 +1197,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
OperationOutcomeIssueComponent iss = new OperationOutcomeIssueComponent(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.ERROR, e.getType());
|
||||
iss.getDetails().setText(e.getMessage());
|
||||
issues.add(iss);
|
||||
return new ValidationResult(IssueSeverity.ERROR, e.getMessage(), e.getError(), issues);
|
||||
return new ValidationResult(IssueSeverity.FATAL, e.getMessage(), e.getError(), issues);
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
localError = e.getMessage();
|
||||
|
@ -1354,6 +1354,11 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
Set<String> unknownSystems = new HashSet<>();
|
||||
|
||||
List<OperationOutcomeIssueComponent> issues = new ArrayList<>();
|
||||
|
||||
String localError = null;
|
||||
String localWarning = null;
|
||||
|
||||
if (options.isUseClient()) {
|
||||
// ok, first we try to validate locally
|
||||
try {
|
||||
|
@ -1365,12 +1370,35 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
txCache.cacheValidation(cacheToken, res, TerminologyCache.TRANSIENT);
|
||||
}
|
||||
return res;
|
||||
} catch (VSCheckerException e) {
|
||||
if (e.isWarning()) {
|
||||
localWarning = e.getMessage();
|
||||
} else {
|
||||
localError = e.getMessage();
|
||||
}
|
||||
if (e.getIssues() != null) {
|
||||
issues.addAll(e.getIssues());
|
||||
}
|
||||
} catch (TerminologyServiceProtectionException e) {
|
||||
OperationOutcomeIssueComponent iss = new OperationOutcomeIssueComponent(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.ERROR, e.getType());
|
||||
iss.getDetails().setText(e.getMessage());
|
||||
issues.add(iss);
|
||||
return new ValidationResult(IssueSeverity.FATAL, e.getMessage(), e.getError(), issues);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (e instanceof NoTerminologyServiceException) {
|
||||
return new ValidationResult(IssueSeverity.ERROR, "No Terminology Service", TerminologyServiceErrorClass.NOSERVICE, null);
|
||||
// e.printStackTrace();
|
||||
localError = e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
if (localError != null && tcc.getClient() == null) {
|
||||
if (unknownSystems.size() > 0) {
|
||||
return new ValidationResult(IssueSeverity.ERROR, localError, TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED, issues).setUnknownSystems(unknownSystems);
|
||||
} else {
|
||||
return new ValidationResult(IssueSeverity.ERROR, localError, TerminologyServiceErrorClass.UNKNOWN, issues);
|
||||
}
|
||||
}
|
||||
if (localWarning != null && tcc.getClient() == null) {
|
||||
return new ValidationResult(IssueSeverity.WARNING,formatMessage(I18nConstants.UNABLE_TO_VALIDATE_CODE_WITHOUT_USING_SERVER, localWarning), TerminologyServiceErrorClass.BLOCKED_BY_OPTIONS, issues);
|
||||
}
|
||||
|
||||
if (!options.isUseServer()) {
|
||||
|
@ -1499,6 +1527,8 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
String system = null;
|
||||
String code = null;
|
||||
String version = null;
|
||||
boolean inactive = false;
|
||||
String status = null;
|
||||
List<OperationOutcomeIssueComponent> issues = new ArrayList<>();
|
||||
|
||||
TerminologyServiceErrorClass err = TerminologyServiceErrorClass.UNKNOWN;
|
||||
|
@ -1516,18 +1546,22 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
version = ((PrimitiveType<?>) p.getValue()).asStringValue();
|
||||
} else if (p.getName().equals("code")) {
|
||||
code = ((PrimitiveType<?>) p.getValue()).asStringValue();
|
||||
} else if (p.getName().equals("inactive")) {
|
||||
inactive = "true".equals(((PrimitiveType<?>) p.getValue()).asStringValue());
|
||||
} else if (p.getName().equals("status")) {
|
||||
status = ((PrimitiveType<?>) p.getValue()).asStringValue();
|
||||
} else if (p.getName().equals("x-caused-by-unknown-system")) {
|
||||
err = TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED;
|
||||
} else if (p.getName().equals("warning-withdrawn")) {
|
||||
OperationOutcomeIssueComponent iss = new OperationOutcomeIssueComponent(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.INFORMATION, org.hl7.fhir.r5.model.OperationOutcome.IssueType.EXPIRED);
|
||||
OperationOutcomeIssueComponent iss = new OperationOutcomeIssueComponent(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.INFORMATION, org.hl7.fhir.r5.model.OperationOutcome.IssueType.BUSINESSRULE);
|
||||
iss.getDetails().setText(formatMessage(vs == null ? I18nConstants.MSG_WITHDRAWN : I18nConstants.MSG_WITHDRAWN_SRC, ((PrimitiveType<?>) p.getValue()).asStringValue(), vs));
|
||||
issues.add(iss);
|
||||
} else if (p.getName().equals("warning-deprecated")) {
|
||||
OperationOutcomeIssueComponent iss = new OperationOutcomeIssueComponent(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.INFORMATION, org.hl7.fhir.r5.model.OperationOutcome.IssueType.EXPIRED);
|
||||
OperationOutcomeIssueComponent iss = new OperationOutcomeIssueComponent(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.INFORMATION, org.hl7.fhir.r5.model.OperationOutcome.IssueType.BUSINESSRULE);
|
||||
iss.getDetails().setText(formatMessage(vs == null ? I18nConstants.MSG_DEPRECATED : I18nConstants.MSG_DEPRECATED_SRC, ((PrimitiveType<?>) p.getValue()).asStringValue(), vs));
|
||||
issues.add(iss);
|
||||
} else if (p.getName().equals("warning-retired")) {
|
||||
OperationOutcomeIssueComponent iss = new OperationOutcomeIssueComponent(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.INFORMATION, org.hl7.fhir.r5.model.OperationOutcome.IssueType.EXPIRED);
|
||||
OperationOutcomeIssueComponent iss = new OperationOutcomeIssueComponent(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.INFORMATION, org.hl7.fhir.r5.model.OperationOutcome.IssueType.BUSINESSRULE);
|
||||
iss.getDetails().setText(formatMessage(vs == null ? I18nConstants.MSG_RETIRED : I18nConstants.MSG_RETIRED_SRC, ((PrimitiveType<?>) p.getValue()).asStringValue(), vs));
|
||||
issues.add(iss);
|
||||
} else if (p.getName().equals("warning-experimental")) {
|
||||
|
@ -1565,7 +1599,8 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
} else {
|
||||
res = new ValidationResult(system, version, new ConceptDefinitionComponent().setCode(code), null).setTxLink(txLog.getLastId());
|
||||
}
|
||||
res.setIssues(issues );
|
||||
res.setIssues(issues);
|
||||
res.setStatus(inactive, status);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -124,6 +124,8 @@ public interface IWorkerContext {
|
|||
private List<OperationOutcomeIssueComponent> issues = new ArrayList<>();
|
||||
private CodeableConcept codeableConcept;
|
||||
private Set<String> unknownSystems;
|
||||
private boolean inactive;
|
||||
private String status;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
@ -339,6 +341,22 @@ public interface IWorkerContext {
|
|||
|
||||
}
|
||||
|
||||
public boolean isInactive() {
|
||||
return inactive;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public ValidationResult setStatus(boolean inactive, String status) {
|
||||
this.inactive = inactive;
|
||||
if (!"inactive".equals(status)) {
|
||||
this.status = status;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class CodingValidationRequest {
|
||||
|
|
|
@ -962,7 +962,10 @@ public class I18nConstants {
|
|||
public static final String MSG_RETIRED_SRC = "MSG_RETIRED_SRC";
|
||||
public static final String MSG_DRAFT_SRC = "MSG_DRAFT_SRC";
|
||||
public static final String MSG_EXPERIMENTAL_SRC = "MSG_EXPERIMENTAL_SRC";
|
||||
public static final String INACTIVE_CODE_WARNING = "INACTIVE_CODE_WARNING";
|
||||
public static final String STATUS_CODE_WARNING = "STATUS_CODE_WARNING";
|
||||
public static final String STATUS_CODE_HINT = "STATUS_CODE_HINT";
|
||||
public static final String STATUS_CODE_WARNING_CODE = "STATUS_CODE_WARNING_CODE";
|
||||
public static final String STATUS_CODE_HINT_CODE = "STATUS_CODE_HINT_CODE";
|
||||
public static final String SD_EXTENSION_URL_MISSING = "SD_EXTENSION_URL_MISSING";
|
||||
public static final String MSG_DEPENDS_ON_DEPRECATED = "MSG_DEPENDS_ON_DEPRECATED";
|
||||
public static final String MSG_DEPENDS_ON_WITHDRAWN = "MSG_DEPENDS_ON_WITHDRAWN";
|
||||
|
|
|
@ -1020,7 +1020,10 @@ MSG_WITHDRAWN_SRC = Reference to withdrawn item {0} from {1}
|
|||
MSG_RETIRED_SRC = Reference to retired item {0} from {1}
|
||||
MSG_EXPERIMENTAL_SRC = Reference to experimental item {0} from {1}
|
||||
MSG_DRAFT_SRC = Reference to draft item {0} from {1}
|
||||
INACTIVE_CODE_WARNING = The code ''{0}'' is valid but is not active
|
||||
STATUS_CODE_WARNING = The code is valid but is {0}
|
||||
STATUS_CODE_HINT = The code is {0}
|
||||
STATUS_CODE_WARNING_CODE = The code ''{1}'' is valid but is {0}
|
||||
STATUS_CODE_HINT_CODE = The code ''{1}'' is {0}
|
||||
SD_ED_TYPE_PROFILE_WRONG_TYPE_one = The type {0} is not in the list of allowed type {1} in the profile {2}
|
||||
SD_ED_TYPE_PROFILE_WRONG_TYPE_other = The type {0} is not in the list of allowed types {1} in the profile {2}
|
||||
MSG_DEPENDS_ON_DEPRECATED = The {0} {1} is deprecated
|
||||
|
|
|
@ -60,6 +60,7 @@ import org.hl7.fhir.r5.model.Resource;
|
|||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
|
||||
import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetUtilities;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.r5.utils.XVerExtensionManager;
|
||||
|
@ -634,6 +635,24 @@ public class BaseValidator implements IValidationContextResourceLoader {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a rule and add a {@link IssueSeverity#WARNING} validation message if the validation fails
|
||||
*
|
||||
* @param thePass
|
||||
* Set this parameter to <code>false</code> if the validation does not pass
|
||||
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
|
||||
*/
|
||||
protected void txIssue(List<ValidationMessage> errors, String ruleDate, String txLink, int line, int col, String path, OperationOutcomeIssueComponent issue) {
|
||||
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);
|
||||
// if (checkMsgId(msg, vmsg)) {
|
||||
errors.add(vmsg);
|
||||
// }
|
||||
// }
|
||||
// return thePass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a rule and add a {@link IssueSeverity#WARNING} validation message if the validation fails. Also, keep track of it later in case we want to remove it if we find a required binding for this element later
|
||||
*
|
||||
|
@ -1312,17 +1331,17 @@ public class BaseValidator implements IValidationContextResourceLoader {
|
|||
if (standardsStatus == StandardsStatus.DEPRECATED) {
|
||||
if (!statusWarnings.contains(vurl+":DEPRECATED")) {
|
||||
statusWarnings.add(vurl+":DEPRECATED");
|
||||
hint(errors, "2023-08-10", IssueType.EXPIRED, element.line(), element.col(), path, false, I18nConstants.MSG_DEPENDS_ON_DEPRECATED, type, vurl);
|
||||
hint(errors, "2023-08-10", IssueType.BUSINESSRULE, element.line(), element.col(), path, false, I18nConstants.MSG_DEPENDS_ON_DEPRECATED, type, vurl);
|
||||
}
|
||||
} else if (standardsStatus == StandardsStatus.WITHDRAWN) {
|
||||
if (!statusWarnings.contains(vurl+":WITHDRAWN")) {
|
||||
statusWarnings.add(vurl+":WITHDRAWN");
|
||||
hint(errors, "2023-08-10", IssueType.EXPIRED, element.line(), element.col(), path, false, I18nConstants.MSG_DEPENDS_ON_WITHDRAWN, type, vurl);
|
||||
hint(errors, "2023-08-10", IssueType.BUSINESSRULE, element.line(), element.col(), path, false, I18nConstants.MSG_DEPENDS_ON_WITHDRAWN, type, vurl);
|
||||
}
|
||||
} else if (ex.getStatus() == PublicationStatus.RETIRED) {
|
||||
if (!statusWarnings.contains(vurl+":RETIRED")) {
|
||||
statusWarnings.add(vurl+":RETIRED");
|
||||
hint(errors, "2023-08-10", IssueType.EXPIRED, element.line(), element.col(), path, false, I18nConstants.MSG_DEPENDS_ON_RETIRED, type, vurl);
|
||||
hint(errors, "2023-08-10", IssueType.BUSINESSRULE, element.line(), element.col(), path, false, I18nConstants.MSG_DEPENDS_ON_RETIRED, type, vurl);
|
||||
}
|
||||
} else if (false && warnOnDraftOrExperimental && source != null) {
|
||||
// for now, this is disabled; these warnings are just everywhere, and it's an intractible problem.
|
||||
|
|
|
@ -125,6 +125,7 @@ import org.hl7.fhir.r5.model.ImplementationGuide;
|
|||
import org.hl7.fhir.r5.model.ImplementationGuide.ImplementationGuideGlobalComponent;
|
||||
import org.hl7.fhir.r5.model.InstantType;
|
||||
import org.hl7.fhir.r5.model.IntegerType;
|
||||
import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
|
||||
import org.hl7.fhir.r5.model.Period;
|
||||
import org.hl7.fhir.r5.model.PrimitiveType;
|
||||
import org.hl7.fhir.r5.model.Quantity;
|
||||
|
@ -1024,9 +1025,15 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
timeTracker.tx(t, "vc "+system+"#"+code+" '"+display+"'");
|
||||
if (s == null)
|
||||
return true;
|
||||
if (s != null && s.isOk()) {
|
||||
for (OperationOutcomeIssueComponent iss : s.getIssues()) {
|
||||
txIssue(errors, "2023-08-19", s.getTxLink(), element.line(), element.col(), path, iss);
|
||||
}
|
||||
}
|
||||
if (s.isOk()) {
|
||||
if (s.getMessage() != null)
|
||||
txWarning(errors, NO_RULE_DATE, s.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, s == null, I18nConstants.TERMINOLOGY_PASSTHROUGH_TX_MESSAGE, s.getMessage(), system, code);
|
||||
|
||||
return true;
|
||||
}
|
||||
if (s.getErrorClass() != null && s.getErrorClass().isInfrastructure())
|
||||
|
@ -1279,6 +1286,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
// ignore this since we can't validate but it doesn't matter..
|
||||
} else {
|
||||
ValidationResult vr = checkCodeOnServer(stack, valueset, cc, true); // we're going to validate the codings directly, so only check the valueset
|
||||
if (vr != null && vr.isOk()) {
|
||||
for (OperationOutcomeIssueComponent iss : vr.getIssues()) {
|
||||
txIssue(errors, "2023-08-19", vr.getTxLink(), element.line(), element.col(), path, iss);
|
||||
}
|
||||
}
|
||||
if (!vr.isOk()) {
|
||||
bindingsOk = false;
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass() == TerminologyServiceErrorClass.NOSERVICE) {
|
||||
|
@ -1356,6 +1368,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
public void checkBindings(List<ValidationMessage> errors, String path, Element element, NodeStack stack, ValueSet valueset, Coding nextCoding) {
|
||||
if (isNotBlank(nextCoding.getCode()) && isNotBlank(nextCoding.getSystem()) && context.supportsSystem(nextCoding.getSystem())) {
|
||||
ValidationResult vr = checkCodeOnServer(stack, valueset, nextCoding, false);
|
||||
if (vr != null && vr.isOk()) {
|
||||
for (OperationOutcomeIssueComponent iss : vr.getIssues()) {
|
||||
txIssue(errors, "2023-08-19", vr.getTxLink(), element.line(), element.col(), path, iss);
|
||||
}
|
||||
}
|
||||
if (vr.getSeverity() != null/* && vr.hasMessage()*/) {
|
||||
if (vr.getSeverity() == IssueSeverity.INFORMATION) {
|
||||
txHint(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, vr.getMessage());
|
||||
|
@ -1416,6 +1433,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
// ignore this since we can't validate but it doesn't matter..
|
||||
} else {
|
||||
ValidationResult vr = checkCodeOnServer(stack, valueset, cc, false); // we're going to validate the codings directly
|
||||
if (vr != null && vr.isOk()) {
|
||||
for (OperationOutcomeIssueComponent iss : vr.getIssues()) {
|
||||
txIssue(errors, "2023-08-19", vr.getTxLink(), element.line(), element.col(), path, iss);
|
||||
}
|
||||
}
|
||||
if (!vr.isOk()) {
|
||||
bindingsOk = false;
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) {
|
||||
|
@ -1465,6 +1487,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
String nextVersion = nextCoding.getVersion();
|
||||
if (isNotBlank(nextCode) && isNotBlank(nextSystem) && context.supportsSystem(nextSystem)) {
|
||||
ValidationResult vr = checkCodeOnServer(stack, nextCode, nextSystem, nextVersion, null, false);
|
||||
if (vr != null && vr.isOk()) {
|
||||
for (OperationOutcomeIssueComponent iss : vr.getIssues()) {
|
||||
txIssue(errors, "2023-08-19", vr.getTxLink(), element.line(), element.col(), path, iss);
|
||||
}
|
||||
}
|
||||
if (!vr.isOk()) {
|
||||
txWarning(errors, NO_RULE_DATE, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CODE_NOTVALID, nextCode, nextSystem);
|
||||
}
|
||||
|
@ -1528,7 +1555,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (binding.getStrength() == BindingStrength.REQUIRED) {
|
||||
removeTrackedMessagesForLocation(errors, element, path);
|
||||
}
|
||||
|
||||
if (vr != null && vr.isOk()) {
|
||||
for (OperationOutcomeIssueComponent iss : vr.getIssues()) {
|
||||
txIssue(errors, "2023-08-19", vr.getTxLink(), element.line(), element.col(), path, iss);
|
||||
}
|
||||
}
|
||||
timeTracker.tx(t, "vc "+system+"#"+code+" '"+display+"'");
|
||||
if (vr != null && !vr.isOk()) {
|
||||
if (vr.IsNoService())
|
||||
|
@ -1671,6 +1702,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
try {
|
||||
long t = System.nanoTime();
|
||||
ValidationResult vr = checkCodeOnServer(stack, valueset, cc, false);
|
||||
if (vr != null && vr.isOk()) {
|
||||
for (OperationOutcomeIssueComponent iss : vr.getIssues()) {
|
||||
txIssue(errors, "2023-08-19", vr.getTxLink(), element.line(), element.col(), path, iss);
|
||||
}
|
||||
}
|
||||
timeTracker.tx(t, "vc "+cc.toString());
|
||||
if (!vr.isOk()) {
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||
|
@ -1708,6 +1744,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
try {
|
||||
long t = System.nanoTime();
|
||||
ValidationResult vr = checkCodeOnServer(stack, valueset, c, true);
|
||||
if (vr != null && vr.isOk()) {
|
||||
for (OperationOutcomeIssueComponent iss : vr.getIssues()) {
|
||||
txIssue(errors, "2023-08-19", vr.getTxLink(), element.line(), element.col(), path, iss);
|
||||
}
|
||||
}
|
||||
|
||||
timeTracker.tx(t, "vc "+c.getSystem()+"#"+c.getCode()+" '"+c.getDisplay()+"'");
|
||||
if (!vr.isOk()) {
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||
|
@ -1737,6 +1779,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
try {
|
||||
long t = System.nanoTime();
|
||||
ValidationResult vr = checkCodeOnServer(stack, valueset, value, baseOptions.withLanguage(stack.getWorkingLang()));
|
||||
if (vr != null && vr.isOk()) {
|
||||
for (OperationOutcomeIssueComponent iss : vr.getIssues()) {
|
||||
txIssue(errors, "2023-08-19", vr.getTxLink(), element.line(), element.col(), path, iss);
|
||||
}
|
||||
}
|
||||
timeTracker.tx(t, "vc "+value);
|
||||
if (!vr.isOk()) {
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||
|
@ -1788,7 +1835,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (theSystem != null && theCode != null && !noTerminologyChecks) {
|
||||
ok = rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, !isValueSet(theSystem), I18nConstants.TERMINOLOGY_TX_SYSTEM_VALUESET2, theSystem) && ok;
|
||||
try {
|
||||
if (checkCode(errors, element, path, theCode, theSystem, theVersion, theDisplay, checkDisplay, stack))
|
||||
if (checkCode(errors, element, path, theCode, theSystem, theVersion, theDisplay, checkDisplay, stack)) {
|
||||
if (theElementCntext != null && theElementCntext.hasBinding()) {
|
||||
ElementDefinitionBindingComponent binding = theElementCntext.getBinding();
|
||||
if (warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, binding != null, I18nConstants.TERMINOLOGY_TX_BINDING_MISSING2, path)) {
|
||||
|
@ -1809,6 +1856,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (binding.getStrength() != BindingStrength.EXAMPLE) {
|
||||
vr = checkCodeOnServer(stack, valueset, c, true);
|
||||
}
|
||||
if (vr != null && vr.isOk()) {
|
||||
for (OperationOutcomeIssueComponent iss : vr.getIssues()) {
|
||||
txIssue(errors, "2023-08-19", vr.getTxLink(), element.line(), element.col(), path, iss);
|
||||
}
|
||||
}
|
||||
|
||||
timeTracker.tx(t, "vc "+c.getSystem()+"#"+c.getCode()+" '"+c.getDisplay()+"'");
|
||||
if (binding.getStrength() == BindingStrength.REQUIRED) {
|
||||
removeTrackedMessagesForLocation(errors, element, path);
|
||||
|
@ -1862,6 +1915,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (STACK_TRACE) e.printStackTrace();
|
||||
rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_ERROR_CODING2, e.getMessage(), e.toString());
|
||||
|
@ -3120,6 +3176,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
vr = checkCodeOnServer(stack, vs, value, options);
|
||||
}
|
||||
if (vr != null && vr.isOk()) {
|
||||
for (OperationOutcomeIssueComponent iss : vr.getIssues()) {
|
||||
txIssue(errors, "2023-08-19", vr.getTxLink(), element.line(), element.col(), path, iss);
|
||||
}
|
||||
}
|
||||
|
||||
timeTracker.tx(t, "vc "+value+"");
|
||||
if (binding.getStrength() == BindingStrength.REQUIRED) {
|
||||
removeTrackedMessagesForLocation(errors, element, path);
|
||||
|
@ -6565,7 +6627,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
|
||||
|
||||
public ValidationResult checkCodeOnServer(NodeStack stack, ValueSet vs, String value, ValidationOptions options) {
|
||||
return context.validateCode(options, value, vs);
|
||||
return checkForInctive(context.validateCode(options, value, vs));
|
||||
}
|
||||
|
||||
// no delay on this one?
|
||||
|
@ -6578,27 +6640,52 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
lang = "en"; // ubiquitious default languauge
|
||||
}
|
||||
codingObserver.seeCode(stack, system, version, code, display);
|
||||
return context.validateCode(baseOptions.withLanguage(lang), system, version, code, checkDisplay ? display : null);
|
||||
return checkForInctive(context.validateCode(baseOptions.withLanguage(lang), system, version, code, checkDisplay ? display : null));
|
||||
}
|
||||
|
||||
public ValidationResult checkCodeOnServer(NodeStack stack, ValueSet valueset, Coding c, boolean checkMembership) {
|
||||
codingObserver.seeCode(stack, c);
|
||||
if (checkMembership) {
|
||||
return context.validateCode(baseOptions.withLanguage(stack.getWorkingLang()).withCheckValueSetOnly(), c, valueset);
|
||||
return checkForInctive( context.validateCode(baseOptions.withLanguage(stack.getWorkingLang()).withCheckValueSetOnly(), c, valueset));
|
||||
} else {
|
||||
return context.validateCode(baseOptions.withLanguage(stack.getWorkingLang()).withNoCheckValueSetMembership(), c, valueset);
|
||||
return checkForInctive(context.validateCode(baseOptions.withLanguage(stack.getWorkingLang()).withNoCheckValueSetMembership(), c, valueset));
|
||||
}
|
||||
}
|
||||
|
||||
public ValidationResult checkCodeOnServer(NodeStack stack, ValueSet valueset, CodeableConcept cc, boolean vsOnly) {
|
||||
codingObserver.seeCode(stack, cc);
|
||||
if (vsOnly) {
|
||||
return context.validateCode(baseOptions.withLanguage(stack.getWorkingLang()).withCheckValueSetOnly(), cc, valueset);
|
||||
return checkForInctive(context.validateCode(baseOptions.withLanguage(stack.getWorkingLang()).withCheckValueSetOnly(), cc, valueset));
|
||||
} else {
|
||||
return context.validateCode(baseOptions.withLanguage(stack.getWorkingLang()), cc, valueset);
|
||||
return checkForInctive(context.validateCode(baseOptions.withLanguage(stack.getWorkingLang()), cc, valueset));
|
||||
}
|
||||
}
|
||||
|
||||
private ValidationResult checkForInctive(ValidationResult res) {
|
||||
if (res == null) {
|
||||
return null;
|
||||
}
|
||||
if (!res.isInactive()) {
|
||||
return res;
|
||||
}
|
||||
org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity lvl = org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.INFORMATION;
|
||||
var status = "not active";
|
||||
if (res.getStatus() != null) {
|
||||
status = res.getStatus();
|
||||
}
|
||||
String code = res.getCode();
|
||||
var op = new OperationOutcomeIssueComponent(lvl, org.hl7.fhir.r5.model.OperationOutcome.IssueType.INVALID);
|
||||
String msgId = null;
|
||||
if (code != null) {
|
||||
msgId = res.isOk() ? I18nConstants.STATUS_CODE_WARNING_CODE : I18nConstants.STATUS_CODE_HINT_CODE;
|
||||
} else {
|
||||
msgId = res.isOk() ? I18nConstants.STATUS_CODE_WARNING : I18nConstants.STATUS_CODE_HINT;
|
||||
}
|
||||
op.getDetails().setText(context.formatMessage(msgId, status, code));
|
||||
res.getIssues().add(op);
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean isSecurityChecks() {
|
||||
return securityChecks;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue