From ced9a748adc2486996ef6b7ab4fda77008654619 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 24 Jun 2022 11:44:29 +0200 Subject: [PATCH] better logging on discriminator misses --- .../cli/services/ValidationService.java | 15 +++++++++++ .../instance/InstanceValidator.java | 25 ++++++++++++++----- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java index 330c856da..f28bf4c4c 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java @@ -4,6 +4,9 @@ import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r5.context.SimpleWorkerContext; import org.hl7.fhir.r5.context.SystemOutLoggingService; import org.hl7.fhir.r5.context.TerminologyCache; +import org.hl7.fhir.r5.conformance.ProfileUtilities; +import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion; +import org.hl7.fhir.r5.context.SimpleWorkerContext.PackageResourceLoader; import org.hl7.fhir.r5.elementmodel.Manager; import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat; import org.hl7.fhir.r5.formats.IParser; @@ -12,6 +15,7 @@ import org.hl7.fhir.r5.formats.XmlParser; import org.hl7.fhir.r5.model.*; import org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity; import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind; +import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule; import org.hl7.fhir.r5.renderers.spreadsheets.CodeSystemSpreadsheetGenerator; import org.hl7.fhir.r5.renderers.spreadsheets.ConceptMapSpreadsheetGenerator; import org.hl7.fhir.r5.renderers.spreadsheets.StructureDefinitionSpreadsheetGenerator; @@ -24,8 +28,11 @@ import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.TimeTracker; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; +import org.hl7.fhir.utilities.i18n.I18nConstants; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; +import org.hl7.fhir.utilities.npm.NpmPackage; import org.hl7.fhir.utilities.npm.ToolsVersion; +import org.hl7.fhir.utilities.npm.NpmPackage.PackageResourceInformation; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.validation.IgLoader; import org.hl7.fhir.validation.ValidationEngine; @@ -39,6 +46,8 @@ import org.hl7.fhir.validation.cli.renderers.ValidationOutputRenderer; import org.hl7.fhir.validation.cli.utils.EngineMode; import org.hl7.fhir.validation.cli.utils.VersionSourceInformation; +import lombok.val; + import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -46,7 +55,9 @@ import java.io.PrintStream; import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class ValidationService { @@ -329,6 +340,8 @@ public class ValidationService { IgLoader igLoader = new IgLoader(validator.getPcm(), validator.getContext(), validator.getVersion(), validator.isDebug()); System.out.println(" - " + validator.getContext().countAllCaches() + " resources (" + tt.milestone() + ")"); igLoader.loadIg(validator.getIgs(), validator.getBinaries(), "hl7.terminology", false); + System.out.print(" Load R5 Extensions"); + System.out.println(" - " + ProfileUtilities.loadR5Extensions(validator.getPcm(), validator.getContext()) + " resources (" + tt.milestone() + ")"); System.out.print(" Terminology server " + cliContext.getTxServer()); String txver = validator.setTerminologyServer(cliContext.getTxServer(), cliContext.getTxLog(), ver); System.out.println(" - Version " + txver + " (" + tt.milestone() + ")"); @@ -378,6 +391,8 @@ public class ValidationService { } + + public String determineVersion(CliContext cliContext) throws Exception { return determineVersion(cliContext, null); } 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 63a0d2bb8..0d9ecc68d 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 @@ -4012,10 +4012,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_MULTIPLE_TYPES_, discriminator, ed.getId(), profile.getUrl(), criteriaElement.typeSummary())); } else throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES, discriminator, ed.getId(), profile.getUrl())); - if (discriminator.isEmpty()) + if (discriminator.isEmpty()) { expression.append(" and $this is " + type); - else + } else { expression.append(" and " + discriminator + " is " + type); + } } else if (s.getType() == DiscriminatorType.PROFILE) { if (criteriaElement.getType().size() == 0) { throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl())); @@ -4036,12 +4037,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat expression.append(" and " + discriminator + ".conformsTo('" + list.get(0).getValue() + "')"); } } else if (s.getType() == DiscriminatorType.EXISTS) { - if (criteriaElement.hasMin() && criteriaElement.getMin() >= 1) + if (criteriaElement.hasMin() && criteriaElement.getMin() >= 1) { expression.append(" and (" + discriminator + ".exists())"); - else if (criteriaElement.hasMax() && criteriaElement.getMax().equals("0")) + } else if (criteriaElement.hasMax() && criteriaElement.getMax().equals("0")) { expression.append(" and (" + discriminator + ".exists().not())"); - else + } else { throw new FHIRException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_ELEMENT_EXISTENCE_BUT_SLICE__NEITHER_SETS_MIN1_OR_MAX0, discriminator, ed.getId())); + } } else if (criteriaElement.hasFixed()) { buildFixedExpression(ed, expression, discriminator, criteriaElement); } else if (criteriaElement.hasPattern()) { @@ -4072,12 +4074,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } timeTracker.fpe(t); ed.setUserData("slice.expression.cache", n); + } else { } ValidatorHostContext shc = hostContext.forSlicing(); boolean pass = evaluateSlicingExpression(shc, element, path, profile, n); if (!pass) { - slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), (context.formatMessage(I18nConstants.DOES_NOT_MATCH_SLICE_, ed.getSliceName())), "discriminator = " + Utilities.escapeXml(n.toString()), null); + slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), (context.formatMessage(I18nConstants.DOES_NOT_MATCH_SLICE_, ed.getSliceName(), n.toString().substring(8).trim())), "discriminator = " + Utilities.escapeXml(n.toString()), null); for (String url : shc.getSliceRecords().keySet()) { slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, stack.getLiteralPath(), url), @@ -4089,6 +4092,16 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat return pass; } + private boolean isBaseDefinition(String url) { + boolean b = url.startsWith("http://hl7.org/fhir/") && !url.substring(40).contains("/"); + return b; + } + + private String descSD(String url) { + StructureDefinition sd = context.fetchResource(StructureDefinition.class, url); + return sd == null ? url : sd.present(); + } + private boolean isProfile(ElementDefinition slicer) { if (slicer == null || !slicer.hasSlicing()) { return false;