From 19760bcaf2baae12f1138323e90893876c9c0520 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 22 Mar 2023 13:44:19 +1100 Subject: [PATCH 1/7] add todo note --- .../org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java | 1 + 1 file changed, 1 insertion(+) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java index 2f93b6e9d..2918297cd 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java @@ -1984,6 +1984,7 @@ public class ProfileUtilities extends TranslatingUtilities { base.getMapping().clear(); base.getMapping().addAll(e.getMapping()); } else if (source.getType().size() == 1 && source.getTypeFirstRep().hasProfile() && !source.getTypeFirstRep().getProfile().get(0).hasExtension(ToolingExtensions.EXT_PROFILE_ELEMENT)) { + // todo: should we change down the profile_element if there's one? String type = source.getTypeFirstRep().getWorkingCode(); if ("Extension".equals(type)) { System.out.println("Can't find Extension definition for "+source.getTypeFirstRep().getProfile().get(0).asStringValue()+" but trying to go on"); From 037f74964e81363a26df94e8ae8b5a4941e77aa9 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 22 Mar 2023 13:44:29 +1100 Subject: [PATCH 2/7] fix type of extension --- .../conv40_50/resources40_50/ImplementationGuide40_50.java | 2 +- .../conv43_50/resources43_50/ImplementationGuide43_50.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/resources40_50/ImplementationGuide40_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/resources40_50/ImplementationGuide40_50.java index 133099991..b2d4e9fc2 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/resources40_50/ImplementationGuide40_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/resources40_50/ImplementationGuide40_50.java @@ -2350,7 +2350,7 @@ public class ImplementationGuide40_50 { tgt.addParameter(convertImplementationGuideDefinitionParameterComponent(t)); } else { org.hl7.fhir.r4.model.Extension e = new org.hl7.fhir.r4.model.Extension(EXT_IG_DEFINITION_PARAMETER); - org.hl7.fhir.r4.model.Extension eCode = new org.hl7.fhir.r4.model.Extension("code", new org.hl7.fhir.r4.model.StringType(t.getCode().getCode())); + org.hl7.fhir.r4.model.Extension eCode = new org.hl7.fhir.r4.model.Extension("code", new org.hl7.fhir.r4.model.CodeType(t.getCode().getCode())); org.hl7.fhir.r4.model.Extension eValue = new org.hl7.fhir.r4.model.Extension("value", new org.hl7.fhir.r4.model.StringType(t.getValue())); e.addExtension(eCode); e.addExtension(eValue); diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv43_50/resources43_50/ImplementationGuide43_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv43_50/resources43_50/ImplementationGuide43_50.java index 139a874dc..d1cbf5d06 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv43_50/resources43_50/ImplementationGuide43_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv43_50/resources43_50/ImplementationGuide43_50.java @@ -2344,7 +2344,7 @@ public class ImplementationGuide43_50 { tgt.addParameter(convertImplementationGuideDefinitionParameterComponent(t)); else { org.hl7.fhir.r4b.model.Extension e = new org.hl7.fhir.r4b.model.Extension(EXT_IG_DEFINITION_PARAMETER); - org.hl7.fhir.r4b.model.Extension eCode = new org.hl7.fhir.r4b.model.Extension("code", new org.hl7.fhir.r4b.model.StringType(t.getCode().getCode())); + org.hl7.fhir.r4b.model.Extension eCode = new org.hl7.fhir.r4b.model.Extension("code", new org.hl7.fhir.r4b.model.CodeType(t.getCode().getCode())); org.hl7.fhir.r4b.model.Extension eValue = new org.hl7.fhir.r4b.model.Extension("value", new org.hl7.fhir.r4b.model.StringType(t.getValue())); e.addExtension(eCode); e.addExtension(eValue); From aba6e8958de1f2c40dc4eea7cf74a0670f5a9f2f Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 22 Mar 2023 13:44:52 +1100 Subject: [PATCH 3/7] fix broken links --- .../src/main/java/org/hl7/fhir/r5/renderers/Renderer.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/Renderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/Renderer.java index 21302ecda..1bb19cc21 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/Renderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/Renderer.java @@ -3,10 +3,12 @@ package org.hl7.fhir.r5.renderers; import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.renderers.utils.RenderingContext; import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules; +import org.hl7.fhir.r5.renderers.utils.RenderingContext.KnownLinkType; import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode; import org.hl7.fhir.r5.utils.TranslatingUtilities; import org.hl7.fhir.utilities.MarkDownProcessor; import org.hl7.fhir.utilities.StandardsStatus; +import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.MarkDownProcessor.Dialect; import org.hl7.fhir.utilities.validation.ValidationOptions; import org.hl7.fhir.utilities.xhtml.XhtmlNode; @@ -76,7 +78,7 @@ public class Renderer extends TranslatingUtilities { public void genStandardsStatus(XhtmlNode td, StandardsStatus ss) { if (ss != null) { td.tx(" "); - XhtmlNode a = td.ah("versions.html#std-process", "Standards Status = "+ss.toDisplay()); + XhtmlNode a = td.ah(Utilities.pathURL(context.getLink(KnownLinkType.SPEC), "versions.html#std-process"), "Standards Status = "+ss.toDisplay()); a.style("padding-left: 3px; padding-right: 3px; border: 1px grey solid; font-weight: bold; color: black; background-color: "+ss.getColor()); a.tx(ss.getAbbrev()); } From 417bae01b16b17f50ab7b6cf6d37903199e4ab09 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 22 Mar 2023 23:05:44 +1100 Subject: [PATCH 4/7] more work to sort out mappings --- .../fhir/r5/conformance/profile/ProfileUtilities.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java index 2918297cd..e2a54f3dd 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java @@ -2281,13 +2281,13 @@ public class ProfileUtilities extends TranslatingUtilities { t.setUserData(UD_DERIVATION_EQUALS, true); } + List list = new ArrayList<>(); + list.addAll(base.getMapping()); + base.getMapping().clear(); + addMappings(base.getMapping(), list); if (derived.hasMapping()) { - List list = new ArrayList<>(); - list.addAll(base.getMapping()); - base.getMapping().clear(); - addMappings(base.getMapping(), list); addMappings(base.getMapping(), derived.getMapping()); - } + } for (ElementDefinitionMappingComponent m : base.getMapping()) { if (m.hasMap()) { m.setMap(m.getMap().trim()); From 05a367b088acbd7c94f3ad09a5b7bc4fc39f3b60 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 22 Mar 2023 23:06:06 +1100 Subject: [PATCH 5/7] validate example URLs in value sets correctly --- .../org/hl7/fhir/utilities/i18n/I18nConstants.java | 2 ++ .../instance/type/ValueSetValidator.java | 14 +++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) 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 dfccc0c6f..4e8a2f701 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 @@ -668,6 +668,8 @@ public class I18nConstants { public static final String MEASURE_SHAREABLE_MISSING_HL7 = "MEASURE_SHAREABLE_MISSING_HL7"; public static final String MEASURE_SHAREABLE_EXTRA_MISSING_HL7 = "MEASURE_SHAREABLE_EXTRA_MISSING_HL7"; public static final String MEASURE_SHAREABLE_EXTRA_MISSING = "MEASURE_SHAREABLE_EXTRA_MISSING"; + public static final String VALUESET_EXAMPLE_SYSTEM_ERROR = "VALUESET_EXAMPLE_SYSTEM_ERROR"; + public static final String VALUESET_EXAMPLE_SYSTEM_HINT = "VALUESET_EXAMPLE_SYSTEM_HINT"; public static final String VALUESET_UNC_SYSTEM_WARNING = "VALUESET_UNC_SYSTEM_WARNING"; public static final String VALUESET_UNC_SYSTEM_WARNING_VER = "VALUESET_UNC_SYSTEM_WARNING_VER"; public static final String VALUESET_IMPORT_UNION_INTERSECTION = "VALUESET_IMPORT_UNION_INTERSECTION"; 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 99c7bbdef..6afaa9d6b 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 @@ -43,13 +43,13 @@ public class ValueSetValidator extends BaseValidator { private InstanceValidator parent; - public ValueSetValidator(IWorkerContext context, TimeTracker timeTracker, InstanceValidator parent, XVerExtensionManager xverManager, Coding jurisdiction) { + public ValueSetValidator(IWorkerContext context, TimeTracker timeTracker, InstanceValidator parent, XVerExtensionManager xverManager, Coding jurisdiction, boolean allowExamples) { super(context, xverManager); source = Source.InstanceValidator; this.timeTracker = timeTracker; this.parent = parent; this.jurisdiction = jurisdiction; - + this.allowExamples = allowExamples; } public boolean validateValueSet(List errors, Element vs, NodeStack stack) { @@ -190,7 +190,15 @@ public class ValueSetValidator extends BaseValidator { if (version == null) { ValidationResult vv = context.validateCode(ValidationOptions.defaults(), new Coding(system, code, null), null); if (vv.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) { - warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stackInc.getLiteralPath(), false, I18nConstants.VALUESET_UNC_SYSTEM_WARNING, system, vv.getMessage()); + if (isExampleUrl(system)) { + if (isAllowExamples()) { + hint(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stackInc.getLiteralPath(), false, I18nConstants.VALUESET_EXAMPLE_SYSTEM_HINT, system); + } else { + rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stackInc.getLiteralPath(), false, I18nConstants.VALUESET_EXAMPLE_SYSTEM_ERROR, system); + } + } else { + warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, stackInc.getLiteralPath(), false, I18nConstants.VALUESET_UNC_SYSTEM_WARNING, system, vv.getMessage()); + } return false; } else { boolean ok = vv.isOk(); From 74a69de9929ec48a4201f0aa2674d201548c961b Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 22 Mar 2023 23:06:33 +1100 Subject: [PATCH 6/7] validate example URLs in value sets correctly --- .../java/org/hl7/fhir/utilities/Utilities.java | 11 ++++++++++- .../src/main/resources/Messages.properties | 4 +++- .../org/hl7/fhir/validation/BaseValidator.java | 14 ++++++++++++++ .../validation/instance/InstanceValidator.java | 11 +---------- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/Utilities.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/Utilities.java index 3eb3b14d2..00bcd60d3 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/Utilities.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/Utilities.java @@ -957,6 +957,15 @@ public class Utilities { return false; } + public static boolean containsInList(String value, String... array) { + if (value == null) + return false; + for (String s : array) + if (value.contains(s)) + return true; + return false; + } + public static boolean existsInList(String value, String... array) { if (value == null) return false; @@ -1991,7 +2000,7 @@ public class Utilities { public static String tail(String url) { int i = url.length()-1; - while (i >= 0 && isTokenChar(url.charAt(i))) { + while (i >= 0 && (isTokenChar(url.charAt(i)) || isDigit(url.charAt(i))) ) { i--; } if (i < 0) { diff --git a/org.hl7.fhir.utilities/src/main/resources/Messages.properties b/org.hl7.fhir.utilities/src/main/resources/Messages.properties index 418dea693..5deb8bc48 100644 --- a/org.hl7.fhir.utilities/src/main/resources/Messages.properties +++ b/org.hl7.fhir.utilities/src/main/resources/Messages.properties @@ -558,6 +558,8 @@ SEARCHPARAMETER_EXP_WRONG = The expression ''{2}'' is not compatible with the ex VALUESET_NO_SYSTEM_WARNING = No System specified, so Concepts and Filters can't be checked VALUESET_INCLUDE_INVALID_CONCEPT_CODE = The code {1} is not valid in the system {0} VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER = The code {2} is not valid in the system {0} version {1} +VALUESET_EXAMPLE_SYSTEM_HINT = Example System ''{0}'' specified, so Concepts and Filters can''t be checked +VALUESET_EXAMPLE_SYSTEM_ERROR = Example System ''{0}'' specified, which is illegal. Concepts and Filters can''t be checked VALUESET_UNC_SYSTEM_WARNING = Unknown System ''{0}'' specified, so Concepts and Filters can''t be checked (Details: {1}) VALUESET_UNC_SYSTEM_WARNING_VER = Unknown System/Version ''{0}'' specified, so Concepts and Filters can''t be checked (Details: {1}) Extension_PROF_Type = The Profile ''{0}'' definition allows for the type {1} but found type {2} @@ -855,7 +857,7 @@ SM_NO_LIST_RULE_ID_NEEDED = A list ruleId should not be provided since this is a SM_LIST_RULE_ID_ONLY_WHEN_SHARE = A ruleId should only be provided when the rule mode is ''share'' SM_RULE_SOURCE_UNASSIGNED = The source statement doesn''t assign a variable to the source - check that this is what is intended SM_TARGET_PATH_MULTIPLE_MATCHES = The target path {0}.{1} refers to the path {2} which is could be a reference to multiple elements ({3}). No further checking can be performed -SM_SOURCE_TYPE_INVALID = The type {0} is not valid in this source context {1}. The possible types are [{2}] +SM_SOURCE_TYPE_INVALID = The type {0} is not valid in the source context {1}. The possible types are [{2}] SM_TARGET_TRANSFORM_PARAM_COUNT_RANGE = Transform {0} takes {1}-{2} parameter(s) but {3} were found SM_TARGET_TRANSFORM_PARAM_COUNT_SINGLE = Transform {0} takes {1} parameter(s) but {2} were found SM_TARGET_TRANSFORM_NOT_CHECKED = Transform {0} not checked dyet diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java index bd7928681..c611b5173 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java @@ -155,6 +155,7 @@ public class BaseValidator implements IValidationContextResourceLoader { protected List messagesToRemove = new ArrayList<>(); private ValidationLevel level = ValidationLevel.HINTS; protected Coding jurisdiction; + protected boolean allowExamples; public BaseValidator(IWorkerContext context, XVerExtensionManager xverManager) { super(); @@ -1231,4 +1232,17 @@ public class BaseValidator implements IValidationContextResourceLoader { String url = cr.getChildValue("url"); return url != null && url.contains("hl7"); } + + public boolean isAllowExamples() { + return this.allowExamples; + } + + public void setAllowExamples(boolean value) { + this.allowExamples = value; + } + + protected boolean isExampleUrl(String url) { + return Utilities.containsInList(url, "example.org", "acme.com", "acme.org"); + + } } \ No newline at end of file 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 be22270cc..ff24a94df 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 @@ -471,7 +471,6 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat private IValidationProfileUsageTracker tracker; private ValidatorHostServices validatorServices; private boolean assumeValidRestReferences; - private boolean allowExamples; private boolean securityChecks; private ProfileUtilities profileUtilities; private boolean crumbTrails; @@ -586,14 +585,6 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat this.assumeValidRestReferences = value; } - public boolean isAllowExamples() { - return this.allowExamples; - } - - public void setAllowExamples(boolean value) { - this.allowExamples = value; - } - public boolean isAllowComments() { return allowComments; } @@ -5043,7 +5034,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } else if (element.getType().equals("StructureMap")) { return new StructureMapValidator(context, timeTracker, fpe, xverManager,profileUtilities, jurisdiction).validateStructureMap(errors, element, stack); } else if (element.getType().equals("ValueSet")) { - return new ValueSetValidator(context, timeTracker, this, xverManager, jurisdiction).validateValueSet(errors, element, stack); + return new ValueSetValidator(context, timeTracker, this, xverManager, jurisdiction, allowExamples).validateValueSet(errors, element, stack); } else { return true; } From def2e782769cfa5867d1b76c20facd6b6a088ce6 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 22 Mar 2023 23:06:50 +1100 Subject: [PATCH 7/7] fix up path in CodeSystemValidator --- .../hl7/fhir/validation/codesystem/CodeSystemValidator.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/codesystem/CodeSystemValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/codesystem/CodeSystemValidator.java index 92d72d754..f8da99620 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/codesystem/CodeSystemValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/codesystem/CodeSystemValidator.java @@ -65,8 +65,10 @@ public class CodeSystemValidator extends BaseValidator { private void checkCodes(Set codes, List list, String path, List errors) { for (ConceptDefinitionComponent cc : list) { - String npath = path+".concept.descendents().where(code = '"+cc.getCode()+"')"; - rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, npath, !codes.contains(cc.getCode()), "Duplicate Code "+cc.getCode()); + String npath = path+".concept.where(code = '"+cc.getCode()+"')"; + if (codes.contains(cc.getCode())) { + rule(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, npath, false, "Duplicate Code "+cc.getCode()); + } codes.add(cc.getCode()); checkCodes(codes, cc.getConcept(), npath, errors); }