alter processing of unknown code systems per discussion at ,https://chat.fhir.org/#narrow/stream/179252-IG-creation/topic/Don't.20error.20when.20you.20can't.20find.20code.20system and implement unknown-codesystems-cause-errors
This commit is contained in:
parent
4603b3ac3c
commit
7fc34e509a
|
@ -125,10 +125,8 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
|||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private ValueSet valueset;
|
||||
private Map<String, ValueSetValidator> inner = new HashMap<>();
|
||||
private ValidationOptions options;
|
||||
|
|
|
@ -1491,7 +1491,7 @@ public class Utilities {
|
|||
}
|
||||
|
||||
public static boolean startsWithInList(String s, Collection<String> list) {
|
||||
if (s == null) {
|
||||
if (s == null || list == null) {
|
||||
return false;
|
||||
}
|
||||
for (String l : list) {
|
||||
|
@ -2304,4 +2304,16 @@ public class Utilities {
|
|||
}
|
||||
}
|
||||
|
||||
public static boolean listValueStartsWith(String s, Set<String> list) {
|
||||
if (s == null || list == null) {
|
||||
return false;
|
||||
}
|
||||
for (String l : list) {
|
||||
if (l.startsWith(s)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,18 +31,19 @@ public class PackageHacker {
|
|||
|
||||
public static void main(String[] args) throws FileNotFoundException, IOException {
|
||||
// new PackageHacker().massEdit(new File("/Users/grahamegrieve/web/hl7.org/fhir"));
|
||||
new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot1/hl7.fhir.r6.core.tgz");
|
||||
new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot1/hl7.fhir.r6.corexml.tgz");
|
||||
new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot1/hl7.fhir.r6.examples.tgz");
|
||||
new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot1/hl7.fhir.r6.expansions.tgz");
|
||||
new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot1/hl7.fhir.r6.search.tgz");
|
||||
new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot2/hl7.fhir.r6.core.tgz");
|
||||
new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot2/hl7.fhir.r6.corexml.tgz");
|
||||
new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot2/hl7.fhir.r6.examples.tgz");
|
||||
new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot2/hl7.fhir.r6.expansions.tgz");
|
||||
new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot2/hl7.fhir.r6.search.tgz");
|
||||
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot1/hl7.fhir.r6.core.tgz");
|
||||
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot1/hl7.fhir.r6.corexml.tgz");
|
||||
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot1/hl7.fhir.r6.examples.tgz");
|
||||
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot1/hl7.fhir.r6.expansions.tgz");
|
||||
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot1/hl7.fhir.r6.search.tgz");
|
||||
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot2/hl7.fhir.r6.core.tgz");
|
||||
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot2/hl7.fhir.r6.corexml.tgz");
|
||||
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot2/hl7.fhir.r6.examples.tgz");
|
||||
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot2/hl7.fhir.r6.expansions.tgz");
|
||||
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/6.0.0-ballot2/hl7.fhir.r6.search.tgz");
|
||||
|
||||
// new PackageHacker().edit(args[0]);
|
||||
// new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/us/core/v311/package.tgz", "http://hl7.org/fhir/us/core/STU3.1.1");
|
||||
new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/us/core/v700/package.tgz", "http://hl7.org/fhir/us/core/STU7");
|
||||
}
|
||||
|
||||
// private void massEdit(File dir) throws IOException {
|
||||
|
@ -91,7 +92,7 @@ public class PackageHacker {
|
|||
// }
|
||||
// }
|
||||
|
||||
private void edit(String name) throws FileNotFoundException, IOException {
|
||||
private void edit(String name, String path) throws FileNotFoundException, IOException {
|
||||
File f = ManagedFileAccess.file(name);
|
||||
if (!f.exists())
|
||||
throw new Error("Unable to find "+f.getAbsolutePath());
|
||||
|
@ -107,15 +108,15 @@ public class PackageHacker {
|
|||
System.out.println("Altering Package "+f.getAbsolutePath());
|
||||
System.out.println(nice(pck.getNpm()));
|
||||
|
||||
if (change(pck.getNpm())) {
|
||||
if (change(pck.getNpm(), path)) {
|
||||
|
||||
System.out.println("Revised Package");
|
||||
System.out.println("=======================");
|
||||
System.out.println(nice(pck.getNpm()));
|
||||
System.out.println("=======================");
|
||||
// System.out.print("save? y/n: ");
|
||||
// int r = System.in.read();
|
||||
// if (r == 'y') {
|
||||
System.out.print("save? y/n: ");
|
||||
int r = System.in.read();
|
||||
if (r == 'y') {
|
||||
f.renameTo(ManagedFileAccess.file(Utilities.changeFileExt(name, ".tgz.bak")));
|
||||
FileOutputStream fso = ManagedFileAccess.outStream(f);
|
||||
try {
|
||||
|
@ -123,7 +124,7 @@ public class PackageHacker {
|
|||
} finally {
|
||||
fso.close();
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,13 +143,15 @@ public class PackageHacker {
|
|||
return JsonParser.compose(json, true);
|
||||
}
|
||||
|
||||
private boolean change(JsonObject npm) throws FileNotFoundException, IOException {
|
||||
// fixVersions(npm, ver);
|
||||
if (npm.has("notForPublication")) {
|
||||
npm.remove("notForPublication");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
private boolean change(JsonObject npm, String path) throws FileNotFoundException, IOException {
|
||||
npm.remove("url");
|
||||
npm.add("url", path);
|
||||
return true;
|
||||
// if (npm.has("notForPublication")) {
|
||||
// npm.remove("notForPublication");
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
}
|
||||
|
||||
private void fixVersionInContent(Map<String, byte[]> content) {
|
||||
|
|
|
@ -226,6 +226,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
@Getter @Setter private boolean allowDoubleQuotesInFHIRPath;
|
||||
@Getter @Setter private boolean checkIPSCodes;
|
||||
@Getter @Setter private BestPracticeWarningLevel bestPracticeLevel;
|
||||
@Getter @Setter private boolean unknownCodeSystemsCauseErrors;
|
||||
@Getter @Setter private Locale locale;
|
||||
@Getter @Setter private List<ImplementationGuide> igs = new ArrayList<>();
|
||||
@Getter @Setter private List<String> extensionDomains = new ArrayList<>();
|
||||
|
@ -289,6 +290,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
fhirPathEngine = other.fhirPathEngine;
|
||||
igLoader = other.igLoader;
|
||||
jurisdiction = other.jurisdiction;
|
||||
unknownCodeSystemsCauseErrors = other.unknownCodeSystemsCauseErrors;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -906,6 +908,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
if (policyAdvisor != null) {
|
||||
validator.setPolicyAdvisor(policyAdvisor);
|
||||
}
|
||||
validator.setUnknownCodeSystemsCauseErrors(unknownCodeSystemsCauseErrors);
|
||||
return validator;
|
||||
}
|
||||
|
||||
|
|
|
@ -163,6 +163,9 @@ public class CliContext {
|
|||
@JsonProperty("bestPracticeLevel")
|
||||
private BestPracticeWarningLevel bestPracticeLevel = BestPracticeWarningLevel.Warning;
|
||||
|
||||
@JsonProperty("unknownCodeSystemsCauseErrors")
|
||||
private boolean unknownCodeSystemsCauseErrors;
|
||||
|
||||
@JsonProperty("baseEngine")
|
||||
public String getBaseEngine() {
|
||||
return baseEngine;
|
||||
|
@ -832,6 +835,7 @@ public class CliContext {
|
|||
Objects.equals(watchMode, that.watchMode) &&
|
||||
Objects.equals(bestPracticeLevel, that.bestPracticeLevel) &&
|
||||
Objects.equals(watchScanDelay, that.watchScanDelay) &&
|
||||
Objects.equals(unknownCodeSystemsCauseErrors, that.unknownCodeSystemsCauseErrors) &&
|
||||
Objects.equals(watchSettleTime, that.watchSettleTime) ;
|
||||
}
|
||||
|
||||
|
@ -839,8 +843,8 @@ public class CliContext {
|
|||
public int hashCode() {
|
||||
return Objects.hash(baseEngine, doNative, extensions, hintAboutNonMustSupport, recursive, doDebug, assumeValidRestReferences, canDoNative, noInternalCaching,
|
||||
noExtensibleBindingMessages, noInvariants, displayWarnings, wantInvariantsInMessages, map, output, outputSuffix, htmlOutput, txServer, sv, txLog, txCache, mapLog, lang, srcLang, tgtLang, fhirpath, snomedCT,
|
||||
targetVer, igs, questionnaireMode, level, profiles, sources, inputs, mode, locale, locations, crumbTrails, forPublication, showTimes, allowExampleUrls, outputStyle, jurisdiction, noUnicodeBiDiControlChars, watchMode, watchScanDelay, watchSettleTime, bestPracticeLevel,
|
||||
htmlInMarkdownCheck, allowDoubleQuotesInFHIRPath, checkIPSCodes);
|
||||
targetVer, igs, questionnaireMode, level, profiles, sources, inputs, mode, locale, locations, crumbTrails, forPublication, showTimes, allowExampleUrls, outputStyle, jurisdiction, noUnicodeBiDiControlChars,
|
||||
watchMode, watchScanDelay, watchSettleTime, bestPracticeLevel, unknownCodeSystemsCauseErrors, htmlInMarkdownCheck, allowDoubleQuotesInFHIRPath, checkIPSCodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -899,6 +903,7 @@ public class CliContext {
|
|||
", bestPracticeLevel=" + bestPracticeLevel +
|
||||
", watchSettleTime=" + watchSettleTime +
|
||||
", watchScanDelay=" + watchScanDelay +
|
||||
", unknownCodeSystemsCauseErrors=" + unknownCodeSystemsCauseErrors +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
@ -956,4 +961,17 @@ public class CliContext {
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
@JsonProperty("unknownCodeSystemsCauseErrors")
|
||||
public boolean isUnknownCodeSystemsCauseErrors() {
|
||||
return unknownCodeSystemsCauseErrors;
|
||||
}
|
||||
|
||||
|
||||
@JsonProperty("unknownCodeSystemsCauseErrors")
|
||||
public void setUnknownCodeSystemsCauseErrors(boolean unknownCodeSystemsCauseErrors) {
|
||||
this.unknownCodeSystemsCauseErrors = unknownCodeSystemsCauseErrors;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -581,6 +581,7 @@ public class ValidationService {
|
|||
}
|
||||
validationEngine.getBundleValidationRules().addAll(cliContext.getBundleValidationRules());
|
||||
validationEngine.setJurisdiction(CodeSystemUtilities.readCoding(cliContext.getJurisdiction()));
|
||||
validationEngine.setUnknownCodeSystemsCauseErrors(cliContext.isUnknownCodeSystemsCauseErrors());
|
||||
TerminologyCache.setNoCaching(cliContext.isNoInternalCaching());
|
||||
validationEngine.prepare(); // generate any missing snapshots
|
||||
System.out.println(" go (" + timeTracker.milestone() + ")");
|
||||
|
|
|
@ -94,8 +94,7 @@ public class Params {
|
|||
public static final String DISABLE_DEFAULT_RESOURCE_FETCHER = "-disable-default-resource-fetcher";
|
||||
public static final String CHECK_IPS_CODES = "-check-ips-codes";
|
||||
public static final String BEST_PRACTICE = "-best-practice";
|
||||
|
||||
|
||||
public static final String UNKNOWN_CODESYSTEMS_CAUSE_ERROR = "-unknown-codesystems-cause-errors";
|
||||
|
||||
public static final String RUN_TESTS = "-run-tests";
|
||||
|
||||
|
@ -320,6 +319,8 @@ public class Params {
|
|||
cliContext.setCrumbTrails(true);
|
||||
} else if (args[i].equals(FOR_PUBLICATION)) {
|
||||
cliContext.setForPublication(true);
|
||||
} else if (args[i].equals(UNKNOWN_CODESYSTEMS_CAUSE_ERROR)) {
|
||||
cliContext.setUnknownCodeSystemsCauseErrors(true);
|
||||
} else if (args[i].equals(VERBOSE)) {
|
||||
cliContext.setCrumbTrails(true);
|
||||
} else if (args[i].equals(ALLOW_EXAMPLE_URLS)) {
|
||||
|
|
|
@ -598,6 +598,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
private boolean example ;
|
||||
private IDigitalSignatureServices signatureServices;
|
||||
private ContextUtilities cu;
|
||||
private boolean unknownCodeSystemsCauseErrors;
|
||||
|
||||
public InstanceValidator(@Nonnull IWorkerContext theContext, @Nonnull IEvaluationContext hostServices, @Nonnull XVerExtensionManager xverManager) {
|
||||
super(theContext, xverManager, false);
|
||||
|
@ -1125,7 +1126,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, null, "no binding on code", false, null) & ok;
|
||||
ok = processTxIssues(errors, s, element, path, false, null, null) & ok;
|
||||
|
||||
if (s.isOk()) {
|
||||
if (s.getMessage() != null && !s.messageIsInIssues()) {
|
||||
|
@ -1381,7 +1382,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, org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.INFORMATION, null, false, null));
|
||||
bh.see(processTxIssues(errors, vr, element, path, false, null, null));
|
||||
timeTracker.tx(t, "vc " + cc.toString());
|
||||
}
|
||||
} catch (CheckCodeOnServerException e) {
|
||||
|
@ -1465,7 +1466,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, notFoundSeverityForBinding(strength), notFoundSeverityNoteForBinding(strength), false, vsRef));
|
||||
bh.see(processTxIssues(errors, vr, element, path, false, vsRef, strength));
|
||||
if (!vr.isOk()) {
|
||||
bindingsOk = false;
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass() == TerminologyServiceErrorClass.NOSERVICE) {
|
||||
|
@ -1533,33 +1534,34 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
return checkDisp;
|
||||
}
|
||||
|
||||
private String notFoundSeverityNoteForBinding(BindingStrength strength) {
|
||||
if (strength == BindingStrength.REQUIRED) {
|
||||
return "error because this is a required binding";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// private String notFoundSeverityNoteForBinding(BindingStrength strength, Set<String> systems) {
|
||||
// if (strength == BindingStrength.REQUIRED &&
|
||||
// (Utilities.listValueStartsWith("http://hl7.org/fhir", systems) || Utilities.listValueStartsWith("http://terminology.hl7.org", systems))) {
|
||||
// return "error because this is a required binding to an HL7 code system";
|
||||
// } else {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * The terminology server will report an error for an unknown code system or version, or a dependent valueset
|
||||
// *
|
||||
// * but we only care for validation if the binding strength is strong enough.
|
||||
// * @param binding
|
||||
// * @return
|
||||
// */
|
||||
// private org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity notFoundSeverityForBinding(BindingStrength strength, String systems) {
|
||||
// if (strength == BindingStrength.REQUIRED &&
|
||||
// (Utilities.listValueStartsWith("http://hl7.org/fhir", systems) || Utilities.listValueStartsWith("http://terminology.hl7.org", systems))) {
|
||||
// return org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.ERROR;
|
||||
// } else if (strength == BindingStrength.REQUIRED || strength == BindingStrength.EXTENSIBLE) {
|
||||
// return org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.WARNING;
|
||||
// } else {
|
||||
// return org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.INFORMATION;
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* The terminology server will report an error for an unknown code system or version, or a dependent valueset
|
||||
*
|
||||
* but we only care for validation if the binding strength is strong enough.
|
||||
* @param binding
|
||||
* @return
|
||||
*/
|
||||
private org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity notFoundSeverityForBinding(BindingStrength strength) {
|
||||
if (strength == BindingStrength.REQUIRED) {
|
||||
return org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.ERROR;
|
||||
} else if (strength == BindingStrength.EXTENSIBLE) {
|
||||
return org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.WARNING;
|
||||
} else {
|
||||
return org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.INFORMATION;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean processTxIssues(List<ValidationMessage> errors, ValidationResult vr, Element element, String path,
|
||||
org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity notFoundLevel, String notFoundNote, boolean ignoreCantInfer, String vsurl) {
|
||||
private boolean processTxIssues(List<ValidationMessage> errors, ValidationResult vr, Element element, String path, boolean ignoreCantInfer, String vsurl, BindingStrength bs) {
|
||||
boolean ok = true;
|
||||
if (vr != null) {
|
||||
for (OperationOutcomeIssueComponent iss : vr.getIssues()) {
|
||||
|
@ -1568,11 +1570,34 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
&& !(ignoreCantInfer || iss.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "cannot-infer"))) {
|
||||
OperationOutcomeIssueComponent i = iss.copy();
|
||||
if (i.getDetails().hasCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "not-found")) {
|
||||
if (notFoundLevel != null && i.getSeverity().isHigherThan(notFoundLevel) || (vsurl != null && i.getDetails().getText().contains(vsurl))) {
|
||||
i.setSeverity(notFoundLevel);
|
||||
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 (notFoundNote != null) {
|
||||
i.getDetails().setText(i.getDetails().getText()+" ("+notFoundNote+")");
|
||||
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+")");
|
||||
}
|
||||
}
|
||||
}
|
||||
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")) {
|
||||
|
@ -1592,7 +1617,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
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, null, "ex-checkBindings", false, null) && ok;
|
||||
ok = processTxIssues(errors, vr, element, path, false, null, null) && ok;
|
||||
|
||||
if (vr.getSeverity() != null && !vr.messageIsInIssues()) {
|
||||
if (vr.getSeverity() == IssueSeverity.INFORMATION) {
|
||||
|
@ -1721,7 +1746,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (strength == BindingStrength.REQUIRED) {
|
||||
removeTrackedMessagesForLocation(errors, element, path);
|
||||
}
|
||||
ok = processTxIssues(errors, vr, element, path, notFoundSeverityForBinding(strength), notFoundSeverityNoteForBinding(strength), false, vsRef) && ok;
|
||||
ok = processTxIssues(errors, vr, element, path, false, vsRef, strength) && ok;
|
||||
timeTracker.tx(t, "vc "+system+"#"+code+" '"+display+"'");
|
||||
if (vr != null && !vr.isOk()) {
|
||||
if (vr.IsNoService())
|
||||
|
@ -1766,6 +1791,21 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
return ok;
|
||||
}
|
||||
|
||||
private Set<String> getUnknownSystems(ValidationResult vr) {
|
||||
if (vr == null) {
|
||||
return null;
|
||||
}
|
||||
if (vr.getUnknownSystems() != null && !vr.getUnknownSystems().isEmpty()) {
|
||||
return vr.getUnknownSystems();
|
||||
}
|
||||
if (vr.getSystem() != null) {
|
||||
Set<String> set = new HashSet<String>();
|
||||
set.add(vr.getSystem());
|
||||
return set;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean convertCDACodeToCodeableConcept(List<ValidationMessage> errors, String path, Element element, StructureDefinition logical, CodeableConcept cc) {
|
||||
boolean ok = true;
|
||||
cc.setText(element.getNamedChildValue("originalText", false));
|
||||
|
@ -1851,7 +1891,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, null, "ex-checkMaxValueSet", false, maxVSUrl) && ok;
|
||||
ok = processTxIssues(errors, vr, element, path, false, maxVSUrl, null) && ok;
|
||||
timeTracker.tx(t, "vc "+cc.toString());
|
||||
if (!vr.isOk()) {
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||
|
@ -1890,7 +1930,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, null, "ex-checkMaxValueSet-2", false, maxVSUrl) && ok;
|
||||
ok = processTxIssues(errors, vr, element, path, false, maxVSUrl, null) && ok;
|
||||
|
||||
timeTracker.tx(t, "vc "+c.getSystem()+"#"+c.getCode()+" '"+c.getDisplay()+"'");
|
||||
if (!vr.isOk()) {
|
||||
|
@ -1921,7 +1961,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, null, "ex-checkMaxValueSet-3", false, maxVSUrl) && ok;
|
||||
ok = processTxIssues(errors, vr, element, path, false, maxVSUrl, null) && ok;
|
||||
timeTracker.tx(t, "vc "+value);
|
||||
if (!vr.isOk()) {
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||
|
@ -2045,7 +2085,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
checked.set(true);
|
||||
vr = checkCodeOnServer(stack, valueset, c);
|
||||
}
|
||||
ok = processTxIssues(errors, vr, element, path, notFoundSeverityForBinding(strength), notFoundSeverityNoteForBinding(strength), strength == BindingStrength.EXTENSIBLE, vsRef) && ok;
|
||||
ok = processTxIssues(errors, vr, element, path, strength == BindingStrength.EXTENSIBLE, vsRef, strength) && ok;
|
||||
|
||||
timeTracker.tx(t, "vc "+c.getSystem()+"#"+c.getCode()+" '"+c.getDisplay()+"'");
|
||||
if (strength == BindingStrength.REQUIRED) {
|
||||
|
@ -3510,7 +3550,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
vr = checkCodeOnServer(stack, vs, value, options);
|
||||
}
|
||||
ok = processTxIssues(errors, vr, element, path, notFoundSeverityForBinding(binding.getStrength()), notFoundSeverityNoteForBinding(binding.getStrength()), binding.getStrength() != BindingStrength.REQUIRED, binding.getValueSet()) && ok;
|
||||
ok = processTxIssues(errors, vr, element, path, binding.getStrength() != BindingStrength.REQUIRED, binding.getValueSet(), binding.getStrength()) && ok;
|
||||
|
||||
timeTracker.tx(t, "vc "+value+"");
|
||||
if (binding.getStrength() == BindingStrength.REQUIRED) {
|
||||
|
@ -7791,4 +7831,14 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
this.fetcher = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isUnknownCodeSystemsCauseErrors() {
|
||||
return unknownCodeSystemsCauseErrors;
|
||||
}
|
||||
|
||||
public void setUnknownCodeSystemsCauseErrors(boolean unknownCodeSystemsCauseErrors) {
|
||||
this.unknownCodeSystemsCauseErrors = unknownCodeSystemsCauseErrors;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -247,9 +247,9 @@ public class ValidationEngineTests {
|
|||
Assertions.assertTrue(checkOutcomes("testObs102", op,
|
||||
"Observation.text.div null error/invalid: Wrong namespace on the XHTML ('null', should be 'http://www.w3.org/1999/xhtml')\n"+
|
||||
"Observation.category null information/business-rule: Reference to experimental CodeSystem http://hl7.org/fhir/observation-category\n"+
|
||||
"Observation.code.coding[2].system null information/not-found: A definition for CodeSystem 'http://acme.org/devices/clinical-codes' could not be found, so the code cannot be validated\n"+
|
||||
"Observation null warning/invalid: Best Practice Recommendation: In general, all observations should have a performer\n"+
|
||||
"Observation null warning/invalid: Best Practice Recommendation: In general, all observations should have an effective[x] ()"));
|
||||
"Observation null warning/invalid: Best Practice Recommendation: In general, all observations should have an effective[x] ()\n"+
|
||||
"Observation.code.coding[2].system null warning/not-found: A definition for CodeSystem 'http://acme.org/devices/clinical-codes' could not be found, so the code cannot be validated"));
|
||||
verifyNoTerminologyRequests(logger);
|
||||
}
|
||||
|
||||
|
@ -265,8 +265,8 @@ public class ValidationEngineTests {
|
|||
System.out.println(" .. load USCore");
|
||||
OperationOutcome op = ve.validate(FhirFormat.XML, TestingUtilities.loadTestResourceStream("validator", "observation301.xml"), null);
|
||||
Assertions.assertTrue(checkOutcomes("test301", op,
|
||||
"Observation.code.coding[3].system null information/not-found: A definition for CodeSystem 'http://acme.org/devices/clinical-codes' could not be found, so the code cannot be validated\n"+
|
||||
"Observation null warning/invalid: Best Practice Recommendation: In general, all observations should have a performer"));
|
||||
"Observation null warning/invalid: Best Practice Recommendation: In general, all observations should have a performer\n"+
|
||||
"Observation.code.coding[3].system null warning/not-found: A definition for CodeSystem 'http://acme.org/devices/clinical-codes' could not be found, so the code cannot be validated"));
|
||||
verifyNoTerminologyRequests(logger);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue