From 42274a7bd31e1743fca3314e7677586ef7e06947 Mon Sep 17 00:00:00 2001 From: markiantorno Date: Wed, 2 Aug 2023 23:02:37 +0000 Subject: [PATCH 1/4] Release: v6.0.24 ## Validator Changes * Create warnings for status on terminology resources * Don't load resources from core examples package ## Other code changes * fix up copy directory for case differences ***NO_CI*** --- org.hl7.fhir.convertors/pom.xml | 2 +- org.hl7.fhir.dstu2/pom.xml | 2 +- org.hl7.fhir.dstu2016may/pom.xml | 2 +- org.hl7.fhir.dstu3/pom.xml | 2 +- org.hl7.fhir.r4/pom.xml | 2 +- org.hl7.fhir.r4b/pom.xml | 2 +- org.hl7.fhir.r5/pom.xml | 2 +- org.hl7.fhir.report/pom.xml | 2 +- org.hl7.fhir.utilities/pom.xml | 2 +- org.hl7.fhir.validation.cli/pom.xml | 2 +- org.hl7.fhir.validation/pom.xml | 2 +- pom.xml | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/org.hl7.fhir.convertors/pom.xml b/org.hl7.fhir.convertors/pom.xml index 183f9efcb..2693b49f7 100644 --- a/org.hl7.fhir.convertors/pom.xml +++ b/org.hl7.fhir.convertors/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24-SNAPSHOT + 6.0.24 ../pom.xml diff --git a/org.hl7.fhir.dstu2/pom.xml b/org.hl7.fhir.dstu2/pom.xml index a93dfb5db..2648d8fb9 100644 --- a/org.hl7.fhir.dstu2/pom.xml +++ b/org.hl7.fhir.dstu2/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24-SNAPSHOT + 6.0.24 ../pom.xml diff --git a/org.hl7.fhir.dstu2016may/pom.xml b/org.hl7.fhir.dstu2016may/pom.xml index 7eac5a17c..79bd52168 100644 --- a/org.hl7.fhir.dstu2016may/pom.xml +++ b/org.hl7.fhir.dstu2016may/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24-SNAPSHOT + 6.0.24 ../pom.xml diff --git a/org.hl7.fhir.dstu3/pom.xml b/org.hl7.fhir.dstu3/pom.xml index 4829ed25a..e08dfeaa4 100644 --- a/org.hl7.fhir.dstu3/pom.xml +++ b/org.hl7.fhir.dstu3/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24-SNAPSHOT + 6.0.24 ../pom.xml diff --git a/org.hl7.fhir.r4/pom.xml b/org.hl7.fhir.r4/pom.xml index 2d5b36252..7a0a367bc 100644 --- a/org.hl7.fhir.r4/pom.xml +++ b/org.hl7.fhir.r4/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24-SNAPSHOT + 6.0.24 ../pom.xml diff --git a/org.hl7.fhir.r4b/pom.xml b/org.hl7.fhir.r4b/pom.xml index a525fd589..147f76c76 100644 --- a/org.hl7.fhir.r4b/pom.xml +++ b/org.hl7.fhir.r4b/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24-SNAPSHOT + 6.0.24 ../pom.xml diff --git a/org.hl7.fhir.r5/pom.xml b/org.hl7.fhir.r5/pom.xml index 40deb6ba4..9eebf1d2d 100644 --- a/org.hl7.fhir.r5/pom.xml +++ b/org.hl7.fhir.r5/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24-SNAPSHOT + 6.0.24 ../pom.xml diff --git a/org.hl7.fhir.report/pom.xml b/org.hl7.fhir.report/pom.xml index d0c646db0..bf3d91cd7 100644 --- a/org.hl7.fhir.report/pom.xml +++ b/org.hl7.fhir.report/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24-SNAPSHOT + 6.0.24 ../pom.xml diff --git a/org.hl7.fhir.utilities/pom.xml b/org.hl7.fhir.utilities/pom.xml index f49299f31..36cb23af5 100644 --- a/org.hl7.fhir.utilities/pom.xml +++ b/org.hl7.fhir.utilities/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24-SNAPSHOT + 6.0.24 ../pom.xml diff --git a/org.hl7.fhir.validation.cli/pom.xml b/org.hl7.fhir.validation.cli/pom.xml index 6490071ec..cefe64de8 100644 --- a/org.hl7.fhir.validation.cli/pom.xml +++ b/org.hl7.fhir.validation.cli/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24-SNAPSHOT + 6.0.24 ../pom.xml diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml index ce37d49e0..e2fbafb32 100644 --- a/org.hl7.fhir.validation/pom.xml +++ b/org.hl7.fhir.validation/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24-SNAPSHOT + 6.0.24 ../pom.xml diff --git a/pom.xml b/pom.xml index ac95e0e8d..fa0498c13 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ HAPI FHIR --> org.hl7.fhir.core - 6.0.24-SNAPSHOT + 6.0.24 pom From 011167a218bec73a2640245d7c36266b522a4244 Mon Sep 17 00:00:00 2001 From: markiantorno Date: Wed, 2 Aug 2023 23:28:12 +0000 Subject: [PATCH 2/4] Updating version to: 6.0.25-SNAPSHOT and incrementing test cases dependency. --- RELEASE_NOTES.md | 5 ++--- org.hl7.fhir.convertors/pom.xml | 2 +- org.hl7.fhir.dstu2/pom.xml | 2 +- org.hl7.fhir.dstu2016may/pom.xml | 2 +- org.hl7.fhir.dstu3/pom.xml | 2 +- org.hl7.fhir.r4/pom.xml | 2 +- org.hl7.fhir.r4b/pom.xml | 2 +- org.hl7.fhir.r5/pom.xml | 2 +- org.hl7.fhir.report/pom.xml | 2 +- org.hl7.fhir.utilities/pom.xml | 2 +- org.hl7.fhir.validation.cli/pom.xml | 2 +- org.hl7.fhir.validation/pom.xml | 2 +- pom.xml | 2 +- 13 files changed, 14 insertions(+), 15 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index af00fbdbe..7b06c6ab5 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,8 +1,7 @@ ## Validator Changes -* Create warnings for status on terminology resources -* Don't load resources from core examples package +* no changes ## Other code changes -* fix up copy directory for case differences +* no changes \ No newline at end of file diff --git a/org.hl7.fhir.convertors/pom.xml b/org.hl7.fhir.convertors/pom.xml index 2693b49f7..87657d416 100644 --- a/org.hl7.fhir.convertors/pom.xml +++ b/org.hl7.fhir.convertors/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24 + 6.0.25-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2/pom.xml b/org.hl7.fhir.dstu2/pom.xml index 2648d8fb9..5797b1a2c 100644 --- a/org.hl7.fhir.dstu2/pom.xml +++ b/org.hl7.fhir.dstu2/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24 + 6.0.25-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2016may/pom.xml b/org.hl7.fhir.dstu2016may/pom.xml index 79bd52168..4ad20750f 100644 --- a/org.hl7.fhir.dstu2016may/pom.xml +++ b/org.hl7.fhir.dstu2016may/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24 + 6.0.25-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu3/pom.xml b/org.hl7.fhir.dstu3/pom.xml index e08dfeaa4..17056f54a 100644 --- a/org.hl7.fhir.dstu3/pom.xml +++ b/org.hl7.fhir.dstu3/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24 + 6.0.25-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r4/pom.xml b/org.hl7.fhir.r4/pom.xml index 7a0a367bc..2e1024bd8 100644 --- a/org.hl7.fhir.r4/pom.xml +++ b/org.hl7.fhir.r4/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24 + 6.0.25-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r4b/pom.xml b/org.hl7.fhir.r4b/pom.xml index 147f76c76..555f61798 100644 --- a/org.hl7.fhir.r4b/pom.xml +++ b/org.hl7.fhir.r4b/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24 + 6.0.25-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r5/pom.xml b/org.hl7.fhir.r5/pom.xml index 9eebf1d2d..694145870 100644 --- a/org.hl7.fhir.r5/pom.xml +++ b/org.hl7.fhir.r5/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24 + 6.0.25-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.report/pom.xml b/org.hl7.fhir.report/pom.xml index bf3d91cd7..6f5dcae12 100644 --- a/org.hl7.fhir.report/pom.xml +++ b/org.hl7.fhir.report/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24 + 6.0.25-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.utilities/pom.xml b/org.hl7.fhir.utilities/pom.xml index 36cb23af5..b3ed07d98 100644 --- a/org.hl7.fhir.utilities/pom.xml +++ b/org.hl7.fhir.utilities/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24 + 6.0.25-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation.cli/pom.xml b/org.hl7.fhir.validation.cli/pom.xml index cefe64de8..c3167bc0d 100644 --- a/org.hl7.fhir.validation.cli/pom.xml +++ b/org.hl7.fhir.validation.cli/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24 + 6.0.25-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml index e2fbafb32..3b892cd43 100644 --- a/org.hl7.fhir.validation/pom.xml +++ b/org.hl7.fhir.validation/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.0.24 + 6.0.25-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index fa0498c13..a97ad5fc0 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ HAPI FHIR --> org.hl7.fhir.core - 6.0.24 + 6.0.25-SNAPSHOT pom From 6d0883468b6a60c4639717166c3d9661f2e5ca58 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 4 Aug 2023 06:12:48 +1000 Subject: [PATCH 3/4] 2023 08 gg extension paths (#1380) * fix problem with whitespace in terminology caching * Support for x-version extensions when generating snapshots * Fix problem with evaluating extension contexts * Produce useful error message when whitespace is wrong in display name * Resolve URL for x-version extensions * render inactive property in expansions * fix tests * ping build * Point to correct test-cases version --------- Co-authored-by: Grahame Grieve Co-authored-by: dotasek --- .../conformance/profile/ProfileUtilities.java | 32 +- .../hl7/fhir/r5/context/TerminologyCache.java | 2 +- .../hl7/fhir/r5/model/ElementDefinition.java | 9 + .../fhir/r5/renderers/ValueSetRenderer.java | 42 ++- .../validation/ValueSetValidator.java | 9 +- .../fhir/r5/utils/XVerExtensionManager.java | 30 ++ .../r5/context/TerminologyCacheTests.java | 2 +- .../txCache/org.hl7.fhir.r5/lang.cache | 39 +++ .../txCache/org.hl7.fhir.r5/loinc.cache | 135 ++++++++ .../txCache/org.hl7.fhir.r5/mimetypes.cache | 39 +++ .../txCache/org.hl7.fhir.r5/ucum.cache | 291 ++++++++++++++++++ .../fhir/utilities/i18n/I18nConstants.java | 1 + .../validation/ValidationMessage.java | 32 ++ .../src/main/resources/Messages.properties | 2 + .../src/main/resources/Messages_es.properties | 5 +- .../instance/InstanceValidator.java | 2 +- .../instance/type/ValueSetValidator.java | 2 +- .../validation/instance/utils/NodeStack.java | 54 +++- pom.xml | 2 +- 19 files changed, 694 insertions(+), 36 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 3b8f9d564..8840a6cdb 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 @@ -846,7 +846,7 @@ public class ProfileUtilities extends TranslatingUtilities { for (UriType u : t.getProfile()) { StructureDefinition sd = context.fetchResource(StructureDefinition.class, u.getValue(), derived); if (sd == null) { - if (xver != null && xver.matchingUrl(u.getValue()) && xver.status(u.getValue()) == XVerExtensionStatus.Valid) { + if (makeXVer().matchingUrl(u.getValue()) && xver.status(u.getValue()) == XVerExtensionStatus.Valid) { sd = xver.makeDefinition(u.getValue()); } } @@ -891,6 +891,13 @@ public class ProfileUtilities extends TranslatingUtilities { } } + private XVerExtensionManager makeXVer() { + if (xver == null) { + xver = new XVerExtensionManager(context); + } + return xver; + } + private ElementDefinition getElementInCurrentContext(String path, List list) { for (int i = list.size() -1; i >= 0; i--) { ElementDefinition t = list.get(i); @@ -1759,7 +1766,7 @@ public class ProfileUtilities extends TranslatingUtilities { if (type.hasProfile()) { sd = context.fetchResource(StructureDefinition.class, type.getProfile().get(0).getValue(), src); if (sd == null) { - if (xver != null && xver.matchingUrl(type.getProfile().get(0).getValue()) && xver.status(type.getProfile().get(0).getValue()) == XVerExtensionStatus.Valid) { + if (makeXVer().matchingUrl(type.getProfile().get(0).getValue()) && xver.status(type.getProfile().get(0).getValue()) == XVerExtensionStatus.Valid) { sd = xver.makeDefinition(type.getProfile().get(0).getValue()); generateSnapshot(context.fetchTypeDefinition("Extension"), sd, sd.getUrl(), webUrl, sd.getName()); } @@ -2297,8 +2304,25 @@ public class ProfileUtilities extends TranslatingUtilities { if (base.hasSliceName()) { profile = base.getType().size() == 1 && base.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, base.getTypeFirstRep().getProfile().get(0).getValue(), srcSD) : null; } - if (profile==null) { - profile = source.getType().size() == 1 && source.getTypeFirstRep().hasProfile() ? context.fetchResource(StructureDefinition.class, source.getTypeFirstRep().getProfile().get(0).getValue(), derivedSrc) : null; + if (profile == null && source.getTypeFirstRep().hasProfile()) { + String pu = source.getTypeFirstRep().getProfile().get(0).getValue(); + profile = context.fetchResource(StructureDefinition.class, pu, derivedSrc); + if (profile == null) { + if (makeXVer().matchingUrl(pu)) { + switch (xver.status(pu)) { + case BadVersion: + throw new FHIRException("Reference to invalid version in extension url " + pu); + case Invalid: + throw new FHIRException("Reference to invalid extension " + pu); + case Unknown: + throw new FHIRException("Reference to unknown extension " + pu); + case Valid: + profile = xver.makeDefinition(pu); + generateSnapshot(context.fetchTypeDefinition("Extension"), profile, profile.getUrl(), context.getSpecUrl(), profile.getName()); + } + } + + } if (profile != null && !"Extension".equals(profile.getType()) && profile.getKind() != StructureDefinitionKind.RESOURCE && profile.getKind() != StructureDefinitionKind.LOGICAL) { // this is a problem - we're kind of hacking things here. The problem is that we sometimes want the details from the profile to override the // inherited attributes, and sometimes not diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java index 7254b80f6..07f56ec80 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java @@ -695,7 +695,7 @@ public class TerminologyCache { } protected String hashJson(String s) { - s = StringUtils.remove(s, ' '); +// s = StringUtils.remove(s, ' '); s = StringUtils.remove(s, '\n'); s = StringUtils.remove(s, '\r'); return String.valueOf(s.hashCode()); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java index 13596d826..0f1556cf4 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java @@ -12748,6 +12748,15 @@ If a pattern[x] is declared on a repeating element, the pattern applies to all r } return b.toString(); } + + public List typeList() { + List res = new ArrayList<>(); + for (TypeRefComponent tr : getType()) { + if (tr.hasCode()) + res.add(tr.getWorkingCode()); + } + return res; + } public String typeSummaryVB() { CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder("|"); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java index 308b7410c..6e1269d8c 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java @@ -198,7 +198,6 @@ public class ValueSetRenderer extends TerminologyRenderer { generateContentModeNotices(x, vs.getExpansion(), vs); generateVersionNotice(x, vs.getExpansion(), vs); - CodeSystem allCS = null; boolean doLevel = false; for (ValueSetExpansionContainsComponent cc : vs.getExpansion().getContains()) { if (cc.hasContains()) { @@ -206,8 +205,9 @@ public class ValueSetRenderer extends TerminologyRenderer { break; } } - + boolean doInactive = checkDoInactive(vs.getExpansion().getContains()); boolean doDefinition = checkDoDefinition(vs.getExpansion().getContains()); + XhtmlNode t = x.table( "codes"); XhtmlNode tr = t.tr(); if (doLevel) @@ -221,6 +221,9 @@ public class ValueSetRenderer extends TerminologyRenderer { scanForDesignations(c, langs, designations); } scanForProperties(vs.getExpansion(), langs, properties); + if (doInactive) { + tr.td().b().tx("Inactive"); + } if (doDefinition) { tr.td().b().tx("Definition"); doDesignations = false; @@ -250,7 +253,7 @@ public class ValueSetRenderer extends TerminologyRenderer { addMapHeaders(tr, maps); for (ValueSetExpansionContainsComponent c : vs.getExpansion().getContains()) { - addExpansionRowToTable(t, vs, c, 1, doLevel, true, doDefinition, maps, allCS, langs, designations, doDesignations, properties); + addExpansionRowToTable(t, vs, c, 1, doLevel, doDefinition, doInactive, maps, langs, designations, doDesignations, properties); } // now, build observed languages @@ -673,6 +676,17 @@ public class ValueSetRenderer extends TerminologyRenderer { return false; } + private boolean checkDoInactive(List contains) { + for (ValueSetExpansionContainsComponent c : contains) { + if (c.hasInactive()) { + return true; + } + if (checkDoInactive(c.getContains())) + return true; + } + return false; + } + private boolean allFromOneSystem(ValueSet vs) { if (vs.getExpansion().getContains().isEmpty()) @@ -754,7 +768,7 @@ public class ValueSetRenderer extends TerminologyRenderer { } } - private void addExpansionRowToTable(XhtmlNode t, ValueSet vs, ValueSetExpansionContainsComponent c, int i, boolean doLevel, boolean doSystem, boolean doDefinition, List maps, CodeSystem allCS, List langs, Map designations, boolean doDesignations, Map properties) throws FHIRFormatError, DefinitionException, IOException { + private void addExpansionRowToTable(XhtmlNode t, ValueSet vs, ValueSetExpansionContainsComponent c, int i, boolean doLevel, boolean doDefinition, boolean doInactive, List maps, List langs, Map designations, boolean doDesignations, Map properties) throws FHIRFormatError, DefinitionException, IOException { XhtmlNode tr = t.tr(); if (ValueSetUtilities.isDeprecated(vs, c)) { tr.setAttribute("style", "background-color: #ffeeee"); @@ -772,19 +786,21 @@ public class ValueSetRenderer extends TerminologyRenderer { String s = Utilities.padLeft("", '\u00A0', i*2); td.attribute("style", "white-space:nowrap").addText(s); addCodeToTable(c.getAbstract(), c.getSystem(), c.getCode(), c.getDisplay(), td); - if (doSystem) { - td = tr.td(); - td.addText(c.getSystem()); - } + td = tr.td(); + td.addText(c.getSystem()); td = tr.td(); if (c.hasDisplayElement()) td.addText(c.getDisplay()); - if (doDefinition) { - CodeSystem cs = allCS; - if (cs == null) - cs = getContext().getWorker().fetchCodeSystem(c.getSystem()); + if (doInactive) { td = tr.td(); + if (c.getInactive()) { + td.tx("inactive"); + } + } + if (doDefinition) { + td = tr.td(); + CodeSystem cs = getContext().getWorker().fetchCodeSystem(c.getSystem()); if (cs != null) { String defn = CodeSystemUtilities.getCodeDefinition(cs, c.getCode()); addMarkdown(td, defn, cs.getWebPath()); @@ -817,7 +833,7 @@ public class ValueSetRenderer extends TerminologyRenderer { addLangaugesToRow(c, langs, tr); } for (ValueSetExpansionContainsComponent cc : c.getContains()) { - addExpansionRowToTable(t, vs, cc, i+1, doLevel, doSystem, doDefinition, maps, allCS, langs, designations, doDesignations, properties); + addExpansionRowToTable(t, vs, cc, i+1, doLevel, doDefinition, doInactive, maps, langs, designations, doDesignations, properties); } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java index 2725724dd..8188dade9 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java @@ -648,6 +648,7 @@ public class ValueSetValidator extends ValueSetProcessBase { if (vcc != null) { vcc.addCoding(vc); } + boolean ws = false; if (code.getDisplay() == null) { return new ValidationResult(code.getSystem(), cs.getVersion(), cc, vc.getDisplay()); } @@ -656,14 +657,20 @@ public class ValueSetValidator extends ValueSetProcessBase { b.append("'"+cc.getDisplay()+"'"); if (code.getDisplay().equalsIgnoreCase(cc.getDisplay())) { return new ValidationResult(code.getSystem(), cs.getVersion(), cc, getPreferredDisplay(cc, cs)); + } else if (Utilities.normalize(code.getDisplay()).equals(Utilities.normalize(cc.getDisplay()))) { + ws = true; } } + for (ConceptDefinitionDesignationComponent ds : cc.getDesignation()) { if (isOkLanguage(ds.getLanguage())) { b.append("'"+ds.getValue()+"'"); if (code.getDisplay().equalsIgnoreCase(ds.getValue())) { return new ValidationResult(code.getSystem(),cs.getVersion(), cc, getPreferredDisplay(cc, cs)); } + if (Utilities.normalize(code.getDisplay()).equalsIgnoreCase(Utilities.normalize(ds.getValue()))) { + ws = true; + } } } // also check to see if the value set has another display @@ -690,7 +697,7 @@ public class ValueSetValidator extends ValueSetProcessBase { String msg = context.formatMessagePlural(options.getLanguages().size(), I18nConstants.NO_VALID_DISPLAY_FOUND, code.getSystem(), code.getCode(), code.getDisplay(), options.langSummary()); return new ValidationResult(IssueSeverity.WARNING, msg, code.getSystem(), cs.getVersion(), cc, getPreferredDisplay(cc, cs), makeIssue(IssueSeverity.WARNING, IssueType.INVALID, path+".display", msg)); } else { - String msg = context.formatMessagePlural(b.count(), I18nConstants.DISPLAY_NAME_FOR__SHOULD_BE_ONE_OF__INSTEAD_OF, code.getSystem(), code.getCode(), b.toString(), code.getDisplay(), options.langSummary()); + String msg = context.formatMessagePlural(b.count(), ws ? I18nConstants.DISPLAY_NAME_WS_FOR__SHOULD_BE_ONE_OF__INSTEAD_OF : I18nConstants.DISPLAY_NAME_FOR__SHOULD_BE_ONE_OF__INSTEAD_OF, code.getSystem(), code.getCode(), b.toString(), code.getDisplay(), options.langSummary()); return new ValidationResult(dispWarningStatus(), msg, code.getSystem(), cs.getVersion(), cc, getPreferredDisplay(cc, cs), makeIssue(dispWarning(), IssueType.INVALID, path+".display", msg)); } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/XVerExtensionManager.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/XVerExtensionManager.java index c2ecfcf9f..6c5b94e3f 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/XVerExtensionManager.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/XVerExtensionManager.java @@ -256,4 +256,34 @@ public class XVerExtensionManager { return v.length() == 3 && Character.isDigit(v.charAt(0)) && v.charAt(1) == '.' && Character.isDigit(v.charAt(2)); } + public String getReference(String url) { + String version = getVersion(url); + String base = VersionUtilities.getSpecUrl(version); + if (base == null) { + return null; + } else { + String path = url.substring(url.indexOf("-")+1); + if (!path.contains(".")) { + return null; + } + String type = path.substring(0, path.indexOf(".")); + if (Utilities.existsInList(type, "Annotation", "Attachment", "Identifier", "CodeableConcept", "Coding", "Quantity", "Duration", "Range", "Period", "Ratio", "RatioRange", "SampledData", "Signature", "HumanName", "Address", "ContactPoint", "Timing")) { + return Utilities.pathURL(base, "datatypes-definitions.html#"+path+"|"+VersionUtilities.getNameForVersion(version)+" "+path); + } + if (Utilities.existsInList(type, "Element", "BackboneElement", "BackboneType", "PrimitiveType", "DataType", "Base")) { + return Utilities.pathURL(base, "types-definitions.html#"+path+"|"+VersionUtilities.getNameForVersion(version)+" "+path); + } + if (Utilities.existsInList(type, "UsageContext", "RelatedArtifact", "DataRequirement", "ParameterDefinition", "TriggerDefinition", "Expression", "ContactDetail", "ExtendedContactDetail", "VirtualServiceDetail", "Availability", "MonetaryComponent", "Contributor")) { + return Utilities.pathURL(base, "metadatatypes-definitions.html#"+path+"|"+VersionUtilities.getNameForVersion(version)+" "+path); + } + if (Utilities.existsInList(type, "Reference", "CodeableReference")) { + return Utilities.pathURL(base, "references-definitions.html#"+path+"|"+VersionUtilities.getNameForVersion(version)+" "+path); + } + if (Utilities.existsInList(type, "Meta")) { + return Utilities.pathURL(base, "resource-definitions.html#"+path+"|"+VersionUtilities.getNameForVersion(version)+" "+path); + } + return Utilities.pathURL(base, type.toLowerCase()+"-definitions.html#"+path+"|"+VersionUtilities.getNameForVersion(version)+" "+path); + } + } + } \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/context/TerminologyCacheTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/context/TerminologyCacheTests.java index 8c4bccb63..96817110c 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/context/TerminologyCacheTests.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/context/TerminologyCacheTests.java @@ -149,7 +149,7 @@ public class TerminologyCacheTests implements ResourceLoaderTests { assertCanonicalResourceEquals(terminologyCapabilities, terminologyCacheB.getTerminologyCapabilities()); assertCanonicalResourceEquals(capabilityStatement, terminologyCacheB.getCapabilityStatement()); - assertValidationResultEquals(codingResultA, terminologyCacheB.getValidation( terminologyCacheA.generateValidationToken(CacheTestUtils.validationOptions, coding, valueSet, new Parameters()))); + assertValidationResultEquals(codingResultA, terminologyCacheB.getValidation(terminologyCacheA.generateValidationToken(CacheTestUtils.validationOptions, coding, valueSet, new Parameters()))); assertValidationResultEquals(codeableConceptResultA, terminologyCacheB.getValidation(terminologyCacheA.generateValidationToken(CacheTestUtils.validationOptions, concept, valueSet, new Parameters()))); assertExpansionOutcomeEquals(expansionOutcomeA,terminologyCacheB.getExpansion(terminologyCacheA.generateExpandToken(valueSet, true))); } diff --git a/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/lang.cache b/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/lang.cache index f78b45815..acd76ade6 100644 --- a/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/lang.cache +++ b/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/lang.cache @@ -12,3 +12,42 @@ e: { "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" } ------------------------------------------------------------------------------------- +{"hierarchical" : false, "valueSet" :{ + "resourceType" : "ValueSet", + "compose" : { + "inactive" : true, + "include" : [{ + "system" : "urn:ietf:bcp:47" + }] + } +}}#### +e: { + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" +} +------------------------------------------------------------------------------------- +{"hierarchical" : false, "valueSet" :{ + "resourceType" : "ValueSet", + "compose" : { + "inactive" : true, + "include" : [{ + "system" : "urn:ietf:bcp:47" + }] + } +}}#### +e: { + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" +} +------------------------------------------------------------------------------------- +{"hierarchical" : false, "valueSet" :{ + "resourceType" : "ValueSet", + "compose" : { + "inactive" : true, + "include" : [{ + "system" : "urn:ietf:bcp:47" + }] + } +}}#### +e: { + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" +} +------------------------------------------------------------------------------------- diff --git a/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/loinc.cache b/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/loinc.cache index 0216bd7fe..0b62b88a1 100644 --- a/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/loinc.cache +++ b/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/loinc.cache @@ -44,3 +44,138 @@ e: { "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" } ------------------------------------------------------------------------------------- +{"hierarchical" : false, "valueSet" :{ + "resourceType" : "ValueSet", + "compose" : { + "inactive" : true, + "include" : [{ + "system" : "http://loinc.org", + "concept" : [{ + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-label", + "valueString" : "A." + }], + "code" : "LA20752-4", + "display" : "Within 24 hours" + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-label", + "valueString" : "B." + }], + "code" : "LA20753-2", + "display" : "After 24 hours but before 3 days" + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-label", + "valueString" : "C." + }], + "code" : "LA20754-0", + "display" : "Three days or later" + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-label", + "valueString" : "D." + }], + "code" : "LA4489-6", + "display" : "Unknown" + }] + }] + } +}}#### +e: { + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" +} +------------------------------------------------------------------------------------- +{"hierarchical" : false, "valueSet" :{ + "resourceType" : "ValueSet", + "compose" : { + "inactive" : true, + "include" : [{ + "system" : "http://loinc.org", + "concept" : [{ + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-label", + "valueString" : "A." + }], + "code" : "LA20752-4", + "display" : "Within 24 hours" + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-label", + "valueString" : "B." + }], + "code" : "LA20753-2", + "display" : "After 24 hours but before 3 days" + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-label", + "valueString" : "C." + }], + "code" : "LA20754-0", + "display" : "Three days or later" + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-label", + "valueString" : "D." + }], + "code" : "LA4489-6", + "display" : "Unknown" + }] + }] + } +}}#### +e: { + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" +} +------------------------------------------------------------------------------------- +{"hierarchical" : false, "valueSet" :{ + "resourceType" : "ValueSet", + "compose" : { + "inactive" : true, + "include" : [{ + "system" : "http://loinc.org", + "concept" : [{ + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-label", + "valueString" : "A." + }], + "code" : "LA20752-4", + "display" : "Within 24 hours" + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-label", + "valueString" : "B." + }], + "code" : "LA20753-2", + "display" : "After 24 hours but before 3 days" + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-label", + "valueString" : "C." + }], + "code" : "LA20754-0", + "display" : "Three days or later" + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-label", + "valueString" : "D." + }], + "code" : "LA4489-6", + "display" : "Unknown" + }] + }] + } +}}#### +e: { + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" +} +------------------------------------------------------------------------------------- diff --git a/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/mimetypes.cache b/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/mimetypes.cache index 5aa448890..d9840e042 100644 --- a/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/mimetypes.cache +++ b/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/mimetypes.cache @@ -12,3 +12,42 @@ e: { "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" } ------------------------------------------------------------------------------------- +{"hierarchical" : false, "valueSet" :{ + "resourceType" : "ValueSet", + "compose" : { + "inactive" : true, + "include" : [{ + "system" : "urn:ietf:bcp:13" + }] + } +}}#### +e: { + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" +} +------------------------------------------------------------------------------------- +{"hierarchical" : false, "valueSet" :{ + "resourceType" : "ValueSet", + "compose" : { + "inactive" : true, + "include" : [{ + "system" : "urn:ietf:bcp:13" + }] + } +}}#### +e: { + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" +} +------------------------------------------------------------------------------------- +{"hierarchical" : false, "valueSet" :{ + "resourceType" : "ValueSet", + "compose" : { + "inactive" : true, + "include" : [{ + "system" : "urn:ietf:bcp:13" + }] + } +}}#### +e: { + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" +} +------------------------------------------------------------------------------------- diff --git a/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/ucum.cache b/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/ucum.cache index ee9e71d25..26af816f9 100644 --- a/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/ucum.cache +++ b/org.hl7.fhir.r5/src/test/resources/txCache/org.hl7.fhir.r5/ucum.cache @@ -96,3 +96,294 @@ e: { "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" } ------------------------------------------------------------------------------------- +{"hierarchical" : false, "valueSet" :{ + "resourceType" : "ValueSet", + "compose" : { + "inactive" : true, + "include" : [{ + "system" : "http://unitsofmeasure.org", + "concept" : [{ + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "second" + }], + "code" : "s", + "display" : "second", + "designation" : [{ + "language" : "zh", + "value" : "秒" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "minute" + }], + "code" : "min", + "display" : "minute", + "designation" : [{ + "language" : "zh", + "value" : "分钟" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "hour" + }], + "code" : "h", + "display" : "hour", + "designation" : [{ + "language" : "zh", + "value" : "小时" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "day" + }], + "code" : "d", + "display" : "day", + "designation" : [{ + "language" : "zh", + "value" : "天" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "week" + }], + "code" : "wk", + "display" : "week", + "designation" : [{ + "language" : "zh", + "value" : "星期" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "month - Normal practice is to use the 'mo' code as a calendar month when calculating the next occurrence." + }], + "code" : "mo", + "display" : "month", + "designation" : [{ + "language" : "zh", + "value" : "月" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "year" + }], + "code" : "a", + "display" : "year", + "designation" : [{ + "language" : "zh", + "value" : "年" + }] + }] + }] + } +}}#### +e: { + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" +} +------------------------------------------------------------------------------------- +{"hierarchical" : false, "valueSet" :{ + "resourceType" : "ValueSet", + "compose" : { + "inactive" : true, + "include" : [{ + "system" : "http://unitsofmeasure.org", + "concept" : [{ + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "second" + }], + "code" : "s", + "display" : "second", + "designation" : [{ + "language" : "zh", + "value" : "秒" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "minute" + }], + "code" : "min", + "display" : "minute", + "designation" : [{ + "language" : "zh", + "value" : "分钟" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "hour" + }], + "code" : "h", + "display" : "hour", + "designation" : [{ + "language" : "zh", + "value" : "小时" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "day" + }], + "code" : "d", + "display" : "day", + "designation" : [{ + "language" : "zh", + "value" : "天" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "week" + }], + "code" : "wk", + "display" : "week", + "designation" : [{ + "language" : "zh", + "value" : "星期" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "month - Normal practice is to use the 'mo' code as a calendar month when calculating the next occurrence." + }], + "code" : "mo", + "display" : "month", + "designation" : [{ + "language" : "zh", + "value" : "月" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "year" + }], + "code" : "a", + "display" : "year", + "designation" : [{ + "language" : "zh", + "value" : "年" + }] + }] + }] + } +}}#### +e: { + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" +} +------------------------------------------------------------------------------------- +{"hierarchical" : false, "valueSet" :{ + "resourceType" : "ValueSet", + "compose" : { + "inactive" : true, + "include" : [{ + "system" : "http://unitsofmeasure.org", + "concept" : [{ + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "second" + }], + "code" : "s", + "display" : "second", + "designation" : [{ + "language" : "zh", + "value" : "秒" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "minute" + }], + "code" : "min", + "display" : "minute", + "designation" : [{ + "language" : "zh", + "value" : "分钟" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "hour" + }], + "code" : "h", + "display" : "hour", + "designation" : [{ + "language" : "zh", + "value" : "小时" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "day" + }], + "code" : "d", + "display" : "day", + "designation" : [{ + "language" : "zh", + "value" : "天" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "week" + }], + "code" : "wk", + "display" : "week", + "designation" : [{ + "language" : "zh", + "value" : "星期" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "month - Normal practice is to use the 'mo' code as a calendar month when calculating the next occurrence." + }], + "code" : "mo", + "display" : "month", + "designation" : [{ + "language" : "zh", + "value" : "月" + }] + }, + { + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition", + "valueString" : "year" + }], + "code" : "a", + "display" : "year", + "designation" : [{ + "language" : "zh", + "value" : "年" + }] + }] + }] + } +}}#### +e: { + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" +} +------------------------------------------------------------------------------------- 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 29610c9f8..a607f0a19 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 @@ -81,6 +81,7 @@ public class I18nConstants { public static final String DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES = "Discriminator__is_based_on_type_but_slice__in__has_no_types"; public static final String DISCRIMINATOR_BAD_PATH = "DISCRIMINATOR_BAD_PATH"; public static final String DISPLAY_NAME_FOR__SHOULD_BE_ONE_OF__INSTEAD_OF = "Display_Name_for__should_be_one_of__instead_of"; + public static final String DISPLAY_NAME_WS_FOR__SHOULD_BE_ONE_OF__INSTEAD_OF = "Display_Name_WS_for__should_be_one_of__instead_of"; public static final String DOCUMENT = "documentmsg"; public static final String DOCUMENT_DATE_REQUIRED = "Bundle_Document_Date_Missing"; public static final String DOCUMENT_DATE_REQUIRED_HTML = "Bundle_Document_Date_Missing_html"; diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/ValidationMessage.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/ValidationMessage.java index b2ec9864b..76028b10b 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/ValidationMessage.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/ValidationMessage.java @@ -859,6 +859,38 @@ public class ValidationMessage implements Comparator, Compara this.ignorableError = ignorableError; return this; } + + public boolean matches(ValidationMessage other) { + if (location == null) { + if (other.location != null) { + return false; + } + } else if (!location.equals(other.location)) { + return false; + } + if (message == null) { + if (other.message != null) { + return false; + } + } else if (!message.equals(other.message)) { + return false; + } + if (messageId == null) { + if (other.messageId != null) { + return false; + } + } else if (!messageId.equals(other.messageId)) { + return false; + } + if (type != other.type) { + return false; + } + if (level != other.level) { + return false; + } + return true; + } + } \ No newline at end of file diff --git a/org.hl7.fhir.utilities/src/main/resources/Messages.properties b/org.hl7.fhir.utilities/src/main/resources/Messages.properties index fab96dfe2..17dcaa914 100644 --- a/org.hl7.fhir.utilities/src/main/resources/Messages.properties +++ b/org.hl7.fhir.utilities/src/main/resources/Messages.properties @@ -468,6 +468,8 @@ Error_parsing_ = Error parsing {0}:{1} Unable_to_connect_to_terminology_server_Use_parameter_tx_na_tun_run_without_using_terminology_services_to_validate_LOINC_SNOMED_ICDX_etc_Error__ = Unable to connect to terminology server. Use parameter ''-tx n/a'' to run without using terminology services to validate LOINC, SNOMED, ICD-X etc. Error = {0} Display_Name_for__should_be_one_of__instead_of_one = Wrong Display Name ''{4}'' for {1}#{2} - should be {3} (for the language(s) ''{5}'') Display_Name_for__should_be_one_of__instead_of_other = Wrong Display Name ''{4}'' for {1}#{2} - should be one of {0} choices: {3} (for the language(s) ''{5}'') +Display_Name_WS_for__should_be_one_of__instead_of_one = Wrong whitespace in Display Name ''{4}'' for {1}#{2} - should be {3} (for the language(s) ''{5}'') +Display_Name_WS_for__should_be_one_of__instead_of_other = Wrong whitespace in Display Name ''{4}'' for {1}#{2} - should be one of {0} choices: {3} (for the language(s) ''{5}'') Unknown_Code__in_ = Unknown Code ''{0}'' in the system ''{1}'' UNKNOWN_CODE__IN_FRAGMENT = Unknown Code ''{0}'' in the system ''{1}'' - note that the code system is labeled as a fragment, so the code may be valid in some other fragment Code_found_in_expansion_however_ = Code found in expansion, however: {0} diff --git a/org.hl7.fhir.utilities/src/main/resources/Messages_es.properties b/org.hl7.fhir.utilities/src/main/resources/Messages_es.properties index b209a888d..74f331de3 100644 --- a/org.hl7.fhir.utilities/src/main/resources/Messages_es.properties +++ b/org.hl7.fhir.utilities/src/main/resources/Messages_es.properties @@ -831,4 +831,7 @@ PRIMITIVE_VALUE_ALTERNATIVES_MESSAGE_many = PRIMITIVE_VALUE_ALTERNATIVES_MESSAGE_other = UNICODE_XML_BAD_CHARS_one = UNICODE_XML_BAD_CHARS_many = -UNICODE_XML_BAD_CHARS_other = \ No newline at end of file +UNICODE_XML_BAD_CHARS_other = +Display_Name_WS_for__should_be_one_of__instead_of_one = +Display_Name_WS_for__should_be_one_of__instead_of_many = +Display_Name_WS_for__should_be_one_of__instead_of_other = 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 b8200a386..9e341a33c 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 @@ -2024,8 +2024,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat return true; } plist.add(p); - } + Collections.sort(plist); // logical paths are a set, but we want a predictable order for error messages for (StructureDefinitionContextComponent ctxt : fixContexts(extUrl, definition.getContext())) { if (ok) { 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 f2663cf5d..86ebb6b4f 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 @@ -71,7 +71,7 @@ public class ValueSetValidator extends BaseValidator { List composes = vs.getChildrenByName("compose"); int cc = 0; for (Element compose : composes) { - ok = validateValueSetCompose(errors, compose, stack.push(compose, cc, null, null), vs.getNamedChildValue("url"), "retired".equals(vs.getNamedChildValue("url"))) & ok; + ok = validateValueSetCompose(errors, compose, stack.push(compose, composes.size() > 1 ? cc : -1, null, null), vs.getNamedChildValue("url"), "retired".equals(vs.getNamedChildValue("url"))) & ok; cc++; } } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java index e3b192153..32df6e98d 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java @@ -2,8 +2,10 @@ package org.hl7.fhir.validation.instance.utils; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.elementmodel.Element; @@ -19,7 +21,7 @@ public class NodeStack { private Element element; private ElementDefinition extension; private String literalPath; // xpath format - private List logicalPaths; // dotted format, various entry points + private Set logicalPaths; // dotted format, various entry points private NodeStack parent; private ElementDefinition type; private String workingLang; @@ -38,7 +40,7 @@ public class NodeStack { literalPath = (initialPath == null ? "" : initialPath+".") + element.getPath(); workingLang = validationLanguage; if (!element.getName().equals(element.fhirType())) { - logicalPaths = new ArrayList<>(); + logicalPaths = new HashSet<>(); logicalPaths.add(element.fhirType()); } } @@ -79,8 +81,8 @@ public class NodeStack { return literalPath == null ? "" : literalPath; } - public List getLogicalPaths() { - return logicalPaths == null ? new ArrayList() : logicalPaths; + public Set getLogicalPaths() { + return logicalPaths == null ? new HashSet() : logicalPaths; } private ElementDefinition getType() { @@ -96,6 +98,9 @@ public class NodeStack { } private NodeStack pushInternal(Element element, int count, ElementDefinition definition, ElementDefinition type, String sep) { + if (definition == null & element.getProperty() != null) { + definition = element.getProperty().getDefinition(); + } NodeStack res = new NodeStack(context); res.ids = ids; res.parent = this; @@ -121,7 +126,7 @@ public class NodeStack { res.literalPath = res.literalPath.substring(0, res.literalPath.lastIndexOf(".")) + "." + en;; } } - res.logicalPaths = new ArrayList(); + res.logicalPaths = new HashSet(); if (type != null) { // type will be null if we on a stitching point of a contained resource, or if.... res.type = type; @@ -131,23 +136,48 @@ public class NodeStack { tn = element.fhirType(); } for (String lp : getLogicalPaths()) { - res.logicalPaths.add(lp + "." + t); - if (t.endsWith("[x]")) { - res.logicalPaths.add(lp + "." + t.substring(0, t.length() - 3) + ".ofType("+type.getPath()+")"); - res.logicalPaths.add(lp + "." + t.substring(0, t.length() - 3) + type.getPath()); + if (isRealPath(lp, t)) { + res.logicalPaths.add(lp + "." + t); + if (t.endsWith("[x]")) { + res.logicalPaths.add(lp + "." + t.substring(0, t.length() - 3) + ".ofType("+type.getPath()+")"); + res.logicalPaths.add(lp + "." + t.substring(0, t.length() - 3) + type.getPath()); + } } } res.logicalPaths.add(tn); } else if (definition != null) { for (String lp : getLogicalPaths()) { - res.logicalPaths.add(lp + "." + element.getName()); + if (isRealPath(lp, element.getName())) { + res.logicalPaths.add(lp + "." + element.getName()); + } } - res.logicalPaths.add(definition.typeSummary()); - } else + if (definition.hasContentReference()) { + res.logicalPaths.add(definition.getContentReference().substring(definition.getContentReference().indexOf("#")+1)); + } else { + res.logicalPaths.addAll(definition.typeList()); + } + } else { res.logicalPaths.addAll(getLogicalPaths()); + } return res; } + private boolean isRealPath(String lp, String t) { + if (Utilities.existsInList(lp, "Element")) { + return Utilities.existsInList(t, "id", "extension"); + } + if (Utilities.existsInList(lp, "BackboneElement", "BackboneType")) { + return Utilities.existsInList(t, "modifierExtension"); + } + if (Utilities.existsInList(lp, "Resource")) { + return Utilities.existsInList(t, "id", "meta", "implicitRules", "language"); + } + if (Utilities.existsInList(lp, "DomainResource")) { + return Utilities.existsInList(t, "text", "contained", "extension", "modifierExtension"); + } + return true; + } + private void setType(ElementDefinition type) { this.type = type; } diff --git a/pom.xml b/pom.xml index a97ad5fc0..e95160b52 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 32.0.1-jre 6.4.1 - 1.3.24 + 1.3.25-SNAPSHOT 2.15.2 5.9.2 1.8.2 From f835c7efe4bad66c649472282ed7660d8f34178d Mon Sep 17 00:00:00 2001 From: dotasek Date: Thu, 3 Aug 2023 16:38:42 -0400 Subject: [PATCH 4/4] Only trim whitespace outside of the json --- .../main/java/org/hl7/fhir/r5/context/TerminologyCache.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java index 07f56ec80..4d574c3c4 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java @@ -695,10 +695,7 @@ public class TerminologyCache { } protected String hashJson(String s) { -// s = StringUtils.remove(s, ' '); - s = StringUtils.remove(s, '\n'); - s = StringUtils.remove(s, '\r'); - return String.valueOf(s.hashCode()); + return String.valueOf(s.trim().hashCode()); } // management