diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java index fd9cade0e..97c434943 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java @@ -2242,15 +2242,29 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte if (Utilities.isAbsoluteUrl(typeName)) { return fetchResource(StructureDefinition.class, typeName); } else { - return fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/"+typeName); + Set types = new HashSet<>(); + types.addAll(fetchTypeDefinitions(typeName)); + types.removeIf(sd -> sd.getDerivation() == TypeDerivationRule.CONSTRAINT); + if (types.size() == 0) { + return null; // throw new FHIRException("Unresolved type "+typeName+" (0)"); + } else if (types.size() == 1) { + return types.iterator().next(); + } else { + types.removeIf(sd -> !sd.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition/")); + if (types.size() != 1) { + throw new FHIRException("Ambiguous type "+typeName+" ("+types.toString()+") (contact Grahame Grieve for investigation)"); + } else { + return types.iterator().next(); + } + } } } - + @Override public List fetchTypeDefinitions(String typeName) { List res = new ArrayList<>(); structures.listAll(res); - res.removeIf(sd -> !sd.hasType() || !sd.getType().equals(typeName)); + res.removeIf(sd -> !sd.hasType() || !(sd.getType().equals(typeName) || sd.getTypeTail().equals(typeName))); return res; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/ContextUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/ContextUtilities.java index 55b335011..480f8061a 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/ContextUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/ContextUtilities.java @@ -32,6 +32,7 @@ import org.hl7.fhir.r5.model.NamingSystem; import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.utilities.OIDUtils; import org.hl7.fhir.utilities.Utilities; +import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.i18n.I18nConstants; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; @@ -156,8 +157,10 @@ public class ContextUtilities implements ProfileKnowledgeProvider { public Set getTypeNameSet() { Set result = new HashSet(); for (StructureDefinition sd : context.fetchResourcesByType(StructureDefinition.class)) { - if (sd.getKind() != StructureDefinitionKind.LOGICAL && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) + if (sd.getKind() != StructureDefinitionKind.LOGICAL && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION && + VersionUtilities.versionsCompatible(context.getVersion(), sd.getFhirVersion().toCode())) { result.add(sd.getName()); + } } return result; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/TypeDetails.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/TypeDetails.java index b23ef74d7..d3a122dca 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/TypeDetails.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/TypeDetails.java @@ -249,6 +249,9 @@ public class TypeDetails { return true; if (tail != null && typesContains(sd.getUrl()+"#"+sd.getType()+tail)) return true; + if ("http://hl7.org/fhir/StructureDefinition/string".equals(sd.getUrl()) && typesContains(FP_String)) { + return true; // this is work around for R3 + } if (sd.hasBaseDefinition()) { if (sd.getType().equals("uri")) sd = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/string"); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java index 166388e88..1422ea1b3 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java @@ -675,7 +675,7 @@ public class FHIRPathEngine { if (ed.fixedType != null) { types = new TypeDetails(CollectionStatus.SINGLETON, ed.fixedType); } else if (ed.getDefinition().getType().isEmpty() || isAbstractType(ed.getDefinition().getType())) { - types = new TypeDetails(CollectionStatus.SINGLETON, ctxt+"#"+t); + types = new TypeDetails(CollectionStatus.SINGLETON, sd.getType()+"#"+t); } else { types = new TypeDetails(CollectionStatus.SINGLETON); for (TypeRefComponent tt : ed.getDefinition().getType()) { diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/SystemExitManager.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/SystemExitManager.java new file mode 100644 index 000000000..81db4c490 --- /dev/null +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/SystemExitManager.java @@ -0,0 +1,43 @@ +package org.hl7.fhir.utilities; + +/** + * A few places in the code, we call System.exit(int) to pass on the exit code to + * other tools (for integration in scripts) + * + * But you don't want to do that while running the failing things under JUnit + * This class does two things + * + * * Remember the exit code while shutdown / cleanup happens + * * Allow for a test case to turn exiting off altogther + * + * @author grahamegrieve + * + */ +public class SystemExitManager { + + private static int error; + private static boolean noExit; + + public static int getError() { + return error; + } + + public static void setError(int error) { + SystemExitManager.error = error; + } + + public static boolean isNoExit() { + return noExit; + } + + public static void setNoExit(boolean noExit) { + SystemExitManager.noExit = noExit; + } + + public static void finish() { + if (!noExit && error > 0) { + System.exit(error); + } + } + +} diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java index 2b27e79a1..3e3097977 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java @@ -922,6 +922,8 @@ public class I18nConstants { public static final String TERMINOLOGY_TX_HINT = "TERMINOLOGY_TX_HINT"; public static final String TERMINOLOGY_TX_WARNING = "TERMINOLOGY_TX_WARNING"; public static final String SD_ED_TYPE_PROFILE_WRONG_TYPE = "SD_ED_TYPE_PROFILE_WRONG_TYPE"; + public static final String VALUESET_CONCEPT_DISPLAY_PRESENCE_MIXED = "VALUESET_CONCEPT_DISPLAY_PRESENCE_MIXED"; + public static final String VALUESET_CONCEPT_DISPLAY_SCT_TAG_MIXED = "VALUESET_CONCEPT_DISPLAY_SCT_TAG_MIXED"; } diff --git a/org.hl7.fhir.utilities/src/main/resources/Messages.properties b/org.hl7.fhir.utilities/src/main/resources/Messages.properties index 5fa6b2064..3ed046162 100644 --- a/org.hl7.fhir.utilities/src/main/resources/Messages.properties +++ b/org.hl7.fhir.utilities/src/main/resources/Messages.properties @@ -977,3 +977,5 @@ TERMINOLOGY_TX_HINT = {1} TERMINOLOGY_TX_WARNING = {1} SD_ED_TYPE_WRONG_TYPE_one = The element has a type {0} which is different to the type {1} on the base profile {2} SD_ED_TYPE_WRONG_TYPE_other = The element has a type {0} which is not in the types {1} on the base profile {2} +VALUESET_CONCEPT_DISPLAY_PRESENCE_MIXED = This include has some concepts with displays and some without - check that this is what is intended +VALUESET_CONCEPT_DISPLAY_SCT_TAG_MIXED = This SNOMED-CT based include has some concepts with semantic tags (FSN terms) and some without (preferred terms) - check that this is what is intended diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java index cdf3bd096..81e1b68c5 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java @@ -594,7 +594,9 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP try { loader.load(ref.getCnt()); } catch (Throwable t) { - System.out.println(t.getMessage()); + if (debug) { + System.out.println("Error during round 1 scanning: "+t.getMessage()); + } } } } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidatorCli.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidatorCli.java index efd50fd06..d6967326e 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidatorCli.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidatorCli.java @@ -67,6 +67,7 @@ POSSIBILITY OF SUCH DAMAGE. import org.apache.commons.text.WordUtils; import org.hl7.fhir.r5.terminologies.JurisdictionUtilities; import org.hl7.fhir.utilities.FileFormat; +import org.hl7.fhir.utilities.SystemExitManager; import org.hl7.fhir.utilities.TimeTracker; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; @@ -163,7 +164,8 @@ public class ValidatorCli { }); } else { displayHelpForDefaultTask(); - }return; + } + return; } readParamsAndExecuteTask(tt, tts, cliContext, args); @@ -310,6 +312,7 @@ public class ValidatorCli { } System.out.println("Done. " + tt.report()+". Max Memory = "+Utilities.describeSize(Runtime.getRuntime().maxMemory())); + SystemExitManager.finish(); } private CliTask selectCliTask(CliContext cliContext, String[] params) { 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 ae376df86..06513a0de 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 @@ -48,6 +48,7 @@ import org.hl7.fhir.r5.renderers.spreadsheets.ValueSetSpreadsheetGenerator; import org.hl7.fhir.r5.terminologies.CodeSystemUtilities; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.utilities.FhirPublication; +import org.hl7.fhir.utilities.SystemExitManager; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.TimeTracker; import org.hl7.fhir.utilities.Utilities; @@ -225,7 +226,9 @@ public class ValidationService { Thread.sleep(watchScanDelay); } } while (watch != ValidatorWatchMode.NONE); - System.exit(ec > 0 ? 1 : 0); + if (ec > 0) { + SystemExitManager.setError(1); + } } private int countErrors(OperationOutcome oo) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/TxTestsTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/TxTestsTask.java index 5a6bdc66f..d85b70e26 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/TxTestsTask.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/TxTestsTask.java @@ -1,5 +1,6 @@ package org.hl7.fhir.validation.cli.tasks; +import org.hl7.fhir.utilities.SystemExitManager; import org.hl7.fhir.utilities.TimeTracker; import org.hl7.fhir.validation.cli.model.CliContext; import org.hl7.fhir.validation.cli.utils.Params; @@ -43,6 +44,7 @@ public class TxTestsTask extends StandaloneTask{ final String tx = Params.getParam(args, Params.TERMINOLOGY); final String filter = Params.getParam(args, Params.FILTER); boolean ok = new TxTester(new TxTester.InternalTxLoader(source, output), tx, false).setOutput(output).execute(version, filter); - System.exit(ok ? 1 : 0); + SystemExitManager.setError(ok ? 1 : 0); + SystemExitManager.finish(); } } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java index 4b155f5a8..e58ddbfea 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java @@ -471,12 +471,14 @@ public class StructureDefinitionValidator extends BaseValidator { } // if we see fixed[x] or pattern[x] applied to a repeating element, we'll give the user a hint } - List constraints = element.getChildrenByName("constraint"); - int cc = 0; - for (Element invariant : constraints) { - ok = validateElementDefinitionInvariant(errors, invariant, stack.push(invariant, cc, null, null), invariantMap, elements, element, element.getNamedChildValue("path"), rootPath, profileUrl) && ok; - cc++; - } + if (snapshot) { // we just don't have enough information to figure out the context in a differential + List constraints = element.getChildrenByName("constraint"); + int cc = 0; + for (Element invariant : constraints) { + ok = validateElementDefinitionInvariant(errors, invariant, stack.push(invariant, cc, null, null), invariantMap, elements, element, element.getNamedChildValue("path"), rootPath, profileUrl) && ok; + cc++; + } + } return ok; } @@ -504,7 +506,7 @@ public class StructureDefinitionValidator extends BaseValidator { Element oldte = te; te = getParent(elements, te); if (te != null) { - exp = tail(oldte, te)+"."+exp; + exp = tail(oldte, te)+".all("+exp+")"; types = getTypesForElement(elements, te); } } @@ -547,13 +549,17 @@ public class StructureDefinitionValidator extends BaseValidator { private List getTypesForElement(List elements, Element element) { List types = new ArrayList<>(); - for (Element tr : element.getChildrenByName("type")) { - String t = tr.getNamedChildValue("code"); - if (t != null) { - if (isAbstractType(t) && hasChildren(element, elements) ) { - types.add(element.getNamedChildValue("path")); - } else { - types.add(t); + if (element.hasChild("path") && !element.getNamedChildValue("path").contains(".")) { + types.add(element.getNamedChildValue("path")); + } else { + for (Element tr : element.getChildrenByName("type")) { + String t = tr.getNamedChildValue("code"); + if (t != null) { + if (isAbstractType(t) && hasChildren(element, elements) ) { + types.add(element.getNamedChildValue("path")); + } else { + types.add(t); + } } } } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java index bf1dfc6af..82bee6298 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java @@ -22,10 +22,79 @@ import org.hl7.fhir.utilities.validation.ValidationOptions; import org.hl7.fhir.validation.BaseValidator; import org.hl7.fhir.validation.TimeTracker; import org.hl7.fhir.validation.instance.InstanceValidator; +import org.hl7.fhir.validation.instance.type.ValueSetValidator.SystemLevelValidator; import org.hl7.fhir.validation.instance.utils.NodeStack; public class ValueSetValidator extends BaseValidator { + public class SystemLevelValidator { + protected List errors; + protected Element inc; + protected NodeStack stack; + + private boolean noDisplay = false; + private boolean hasDisplay = false; + protected SystemLevelValidator(List errors, Element inc, NodeStack stack) { + super(); + this.errors = errors; + this.inc = inc; + this.stack = stack; + } + + public void checkConcept(String code, String display) { + if (Utilities.noString(display)) { + noDisplay = true; + } else { + hasDisplay = true; + } + } + + public void finish() { + hint(errors, "2023-07-21", IssueType.BUSINESSRULE, inc.line(), inc.col(), stack.getLiteralPath(), !(noDisplay && hasDisplay), I18nConstants.VALUESET_CONCEPT_DISPLAY_PRESENCE_MIXED); + } + } + + public class SnomedCTValidator extends SystemLevelValidator { + private boolean noTag = false; + private boolean hasTag = false; + + protected SnomedCTValidator(List errors, Element inc, NodeStack stack) { + super(errors, inc, stack); + } + public void checkConcept(String code, String display) { + super.checkConcept(code, display); + if (!Utilities.noString(display)) { + boolean tagged = display.endsWith(")") && display.indexOf("(") > display.length() - 20; + if (tagged) { + hasTag = true; + } else { + noTag = true; + } + } + } + public void finish() { + hint(errors, "2023-07-21", IssueType.BUSINESSRULE, inc.line(), inc.col(), stack.getLiteralPath(), !(noTag && hasTag), I18nConstants.VALUESET_CONCEPT_DISPLAY_SCT_TAG_MIXED); + } + } + + public class GeneralValidator extends SystemLevelValidator { + + protected GeneralValidator(List errors, Element inc, NodeStack stack) { + super(errors, inc, stack); + } + + } + + private SystemLevelValidator getSystemValidator(String system, List errors, Element inc, NodeStack stack) { + if (system == null) { + return new GeneralValidator(errors, inc, stack); + } + switch (system) { + case "http://snomed.info/sct" :return new SnomedCTValidator(errors, inc, stack); + default: return new GeneralValidator(errors, inc, stack); + } + } + public class VSCodingValidationRequest extends CodingValidationRequest { private NodeStack stack; @@ -139,6 +208,8 @@ public class ValueSetValidator extends BaseValidator { } List concepts = include.getChildrenByName("concept"); List filters = include.getChildrenByName("filter"); + + SystemLevelValidator slv = getSystemValidator(system, errors, include, stack); if (!Utilities.noString(system)) { boolean systemOk = true; int cc = 0; @@ -147,10 +218,10 @@ public class ValueSetValidator extends BaseValidator { for (Element concept : concepts) { // we treat the first differently because we want to know if tbe system is worth validating. if it is, then we batch the rest if (first) { - systemOk = validateValueSetIncludeConcept(errors, concept, stack, stack.push(concept, cc, null, null), system, version); + systemOk = validateValueSetIncludeConcept(errors, concept, stack, stack.push(concept, cc, null, null), system, version, slv); first = false; } else if (systemOk) { - batch.add(prepareValidateValueSetIncludeConcept(errors, concept, stack.push(concept, cc, null, null), system, version)); + batch.add(prepareValidateValueSetIncludeConcept(errors, concept, stack.push(concept, cc, null, null), system, version, slv)); } cc++; } @@ -180,19 +251,24 @@ public class ValueSetValidator extends BaseValidator { int cf = 0; for (Element filter : filters) { - if (systemOk && !validateValueSetIncludeFilter(errors, include, stack.push(filter, cf, null, null), system, version)) { + if (systemOk && !validateValueSetIncludeFilter(errors, include, stack.push(filter, cf, null, null), system, version, slv)) { systemOk = false; } cf++; } + slv.finish(); } else { warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stack.getLiteralPath(), filters.size() == 0 && concepts.size() == 0, I18nConstants.VALUESET_NO_SYSTEM_WARNING); } return ok; } - private boolean validateValueSetIncludeConcept(List errors, Element concept, NodeStack stackInc, NodeStack stack, String system, String version) { + + private boolean validateValueSetIncludeConcept(List errors, Element concept, NodeStack stackInc, NodeStack stack, String system, String version, SystemLevelValidator slv) { String code = concept.getChildValue("code"); + String display = concept.getChildValue("display"); + slv.checkConcept(code, display); + if (version == null) { ValidationResult vv = context.validateCode(ValidationOptions.defaults(), new Coding(system, code, null), null); if (vv.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) { @@ -229,8 +305,11 @@ public class ValueSetValidator extends BaseValidator { return true; } - private VSCodingValidationRequest prepareValidateValueSetIncludeConcept(List errors, Element concept, NodeStack stack, String system, String version) { + private VSCodingValidationRequest prepareValidateValueSetIncludeConcept(List errors, Element concept, NodeStack stack, String system, String version, SystemLevelValidator slv) { String code = concept.getChildValue("code"); + String display = concept.getChildValue("display"); + slv.checkConcept(code, display); + Coding c = new Coding(system, code, null); if (version != null) { c.setVersion(version); @@ -238,7 +317,11 @@ public class ValueSetValidator extends BaseValidator { return new VSCodingValidationRequest(stack, c); } - private boolean validateValueSetIncludeFilter(List errors, Element include, NodeStack push, String system, String version) { + private boolean validateValueSetIncludeFilter(List errors, Element filter, NodeStack push, String system, String version, SystemLevelValidator slv) { +// +// String display = concept.getChildValue("display"); +// slv.checkConcept(code, display); + return true; } } diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/TerminologyServiceTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/TerminologyServiceTests.java index 87a2b62bc..20a3a8fee 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/TerminologyServiceTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/TerminologyServiceTests.java @@ -32,6 +32,7 @@ import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent; import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent; import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.UriType; +import org.hl7.fhir.r5.model.CanonicalType; import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; import org.hl7.fhir.r5.model.CodeableConcept; @@ -290,7 +291,7 @@ public class TerminologyServiceTests { } if (vm.getUnknownSystems() != null) { for (String s : vm.getUnknownSystems()) { - res.addParameter("x-caused-by-unknown-system", new UriType(s)); + res.addParameter("x-caused-by-unknown-system", new CanonicalType(s)); } } if (vm.getIssues().size() > 0) { diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/CDAValidationTest.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/CDAValidationTest.java index 39a41cf26..aebf5f9b3 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/CDAValidationTest.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/CDAValidationTest.java @@ -2,18 +2,22 @@ package org.hl7.fhir.validation.tests; import org.hl7.fhir.r4.context.SimpleWorkerContext; import org.hl7.fhir.r5.test.utils.TestingUtilities; +import org.hl7.fhir.utilities.SystemExitManager; +import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.validation.ValidatorCli; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -@Disabled public class CDAValidationTest { private SimpleWorkerContext context; @Test public void test() throws Exception { - ValidatorCli.main(new String[] {TestingUtilities.loadTestResource("ccda.xml"), "-ig", "hl7.fhir.cda"}); + String fn = TestingUtilities.tempFile("cda", "cda.xml"); + TextFile.stringToFile(TestingUtilities.loadTestResource("cda/cda-original.xml"), fn); + SystemExitManager.setNoExit(true); + ValidatorCli.main(new String[] {fn, "-ig", "hl7.cda.uv.core#current"}); } } \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/all-systems.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/all-systems.cache index 509367d11..f71ba85ea 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/all-systems.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/all-systems.cache @@ -126,3 +126,20 @@ v: { "system" : "urn:ietf:bcp:47" } ------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://unstats.un.org/unsd/methods/m49/m49.htm", + "code" : "001", + "display" : "World" +}, "url": "http://hl7.org/fhir/ValueSet/jurisdiction", "version": "5.0.0", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "displayWarningMode":"false", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "World", + "code" : "001", + "system" : "http://unstats.un.org/unsd/methods/m49/m49.htm" +} +------------------------------------------------------------------------------------- diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/http___unstats.un.org_unsd_methods_m49_m49.htm.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/http___unstats.un.org_unsd_methods_m49_m49.htm.cache new file mode 100644 index 000000000..ecfc67f33 --- /dev/null +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/http___unstats.un.org_unsd_methods_m49_m49.htm.cache @@ -0,0 +1,33 @@ +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://unstats.un.org/unsd/methods/m49/m49.htm", + "code" : "001" +}, "url": "http://hl7.org/fhir/ValueSet/jurisdiction--2", "version": "5.0.0", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "displayWarningMode":"false", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "World", + "code" : "001", + "system" : "http://unstats.un.org/unsd/methods/m49/m49.htm" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://unstats.un.org/unsd/methods/m49/m49.htm", + "code" : "001" +}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "World", + "code" : "001", + "system" : "http://unstats.un.org/unsd/methods/m49/m49.htm" +} +------------------------------------------------------------------------------------- diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/snomed.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/snomed.cache index 4996fd9cc..015bf8801 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/snomed.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/snomed.cache @@ -822,3 +822,54 @@ v: { "version" : "http://snomed.info/sct/900000000000207008/version/20230131" } ------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://snomed.info/sct", + "code" : "230993007" +}, "valueSet" :null, "langs":"[en-US, en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"true", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Worsening", + "code" : "230993007", + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://snomed.info/sct", + "code" : "385633008" +}, "valueSet" :null, "langs":"[en-US, en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"true", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Improving (qualifier value)", + "code" : "385633008", + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://snomed.info/sct", + "code" : "260388006" +}, "valueSet" :null, "langs":"[en-US, en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"true", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "No status change", + "code" : "260388006", + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" +} +-------------------------------------------------------------------------------------